// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:file/memory.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/ios/devices.dart';
import 'package:flutter_tools/src/ios/ios_deploy.dart';
import 'package:flutter_tools/src/ios/iproxy.dart';
import 'package:flutter_tools/src/ios/mac.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/macos/xcode.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:mockito/mockito.dart';
import 'package:fake_async/fake_async.dart';
import 'package:vm_service/vm_service.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fake_process_manager.dart';
import '../../src/fakes.dart';

List<String> _xattrArgs(FlutterProject flutterProject) {
  return <String>[
    'xattr',
    '-r',
    '-d',
    'com.apple.FinderInfo',
    flutterProject.ios.hostAppRoot.path,
  ];
}

const List<String> kRunReleaseArgs = <String>[
  'xcrun',
  'xcodebuild',
  '-configuration',
  'Release',
  '-quiet',
  '-workspace',
  'Runner.xcworkspace',
  '-scheme',
  'Runner',
  'BUILD_DIR=/build/ios',
  '-sdk',
  'iphoneos',
  'ONLY_ACTIVE_ARCH=YES',
  'ARCHS=arm64',
  'FLUTTER_SUPPRESS_ANALYTICS=true',
  'COMPILER_INDEX_STORE_ENABLE=NO',
];

const String kConcurrentBuildErrorMessage = '''
"/Developer/Xcode/DerivedData/foo/XCBuildData/build.db":
database is locked
Possibly there are two concurrent builds running in the same filesystem location.
''';

final FakePlatform macPlatform = FakePlatform(
  operatingSystem: 'macos',
  environment: <String, String>{},
);

void main() {
  Artifacts artifacts;
  String iosDeployPath;

  setUp(() {
    artifacts = Artifacts.test();
    iosDeployPath = artifacts.getArtifactPath(Artifact.iosDeploy, platform: TargetPlatform.ios);
  });

  group('IOSDevice.startApp succeeds in release mode', () {
    FileSystem fileSystem;
    FakeProcessManager processManager;
    BufferLogger logger;
    MockXcode mockXcode;
    MockXcodeProjectInterpreter mockXcodeProjectInterpreter;

    setUp(() {
      logger = BufferLogger.test();
      fileSystem = MemoryFileSystem.test();
      processManager = FakeProcessManager.list(<FakeCommand>[]);

      mockXcodeProjectInterpreter = MockXcodeProjectInterpreter();
      when(mockXcodeProjectInterpreter.isInstalled).thenReturn(true);
      when(mockXcodeProjectInterpreter.getInfo(any, projectFilename: anyNamed('projectFilename'))).thenAnswer(
          (_) {
          return Future<XcodeProjectInfo>.value(XcodeProjectInfo(
            <String>['Runner'],
            <String>['Debug', 'Release'],
            <String>['Runner'],
            logger,
          ));
        }
      );
      mockXcode = MockXcode();
      when(mockXcode.isRequiredVersionSatisfactory).thenReturn(true);
      when(mockXcode.xcrunCommand()).thenReturn(<String>['xcrun']);
      fileSystem.file('foo/.packages')
        ..createSync(recursive: true)
        ..writeAsStringSync('\n');
    });

    testUsingContext('with buildable app', () async {
      final IOSDevice iosDevice = setUpIOSDevice(
        fileSystem: fileSystem,
        processManager: processManager,
        logger: logger,
        artifacts: artifacts,
      );
      setUpIOSProject(fileSystem);
      final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
      final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter', 'My Super Awesome App.app');

      processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
      processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
      processManager.addCommand(const FakeCommand(command: <String>[...kRunReleaseArgs, '-showBuildSettings']));
      processManager.addCommand(FakeCommand(
        command: <String>[
          iosDeployPath,
          '--id',
          '123',
          '--bundle',
          'build/ios/iphoneos/My Super Awesome App.app',
          '--no-wifi',
          '--justlaunch',
          '--args',
          const <String>[
            '--enable-dart-profiling',
            '--disable-service-auth-codes',
          ].join(' ')
        ])
      );

      final LaunchResult launchResult = await iosDevice.startApp(
        buildableIOSApp,
        debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
        platformArgs: <String, Object>{},
      );

      expect(launchResult.started, true);
      expect(processManager.hasRemainingExpectations, false);
    }, overrides: <Type, Generator>{
      ProcessManager: () => processManager,
      FileSystem: () => fileSystem,
      Logger: () => logger,
      Platform: () => macPlatform,
      XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
      Xcode: () => mockXcode,
    });

    testUsingContext('with flaky buildSettings call', () async {
      LaunchResult launchResult;
      FakeAsync().run((FakeAsync time) {
        final IOSDevice iosDevice = setUpIOSDevice(
          fileSystem: fileSystem,
          processManager: processManager,
          logger: logger,
          artifacts: artifacts,
        );
        setUpIOSProject(fileSystem);
        final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
        final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter', 'My Super Awesome App.app');

        processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
        processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
        // The first showBuildSettings call should timeout.
        processManager.addCommand(
          const FakeCommand(
            command: <String>[...kRunReleaseArgs, '-showBuildSettings'],
            duration: Duration(minutes: 5), // this is longer than the timeout of 1 minute.
          ));
        // The second call succeeds and is made after the first times out.
        processManager.addCommand(
          const FakeCommand(
            command: <String>[...kRunReleaseArgs, '-showBuildSettings'],
            exitCode: 0,
          ));
        processManager.addCommand(FakeCommand(
          command: <String>[
            iosDeployPath,
            '--id',
            '123',
            '--bundle',
            'build/ios/iphoneos/My Super Awesome App.app',
            '--no-wifi',
            '--justlaunch',
            '--args',
            const <String>[
              '--enable-dart-profiling',
              '--disable-service-auth-codes',
            ].join(' ')
          ])
        );

        iosDevice.startApp(
          buildableIOSApp,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
          platformArgs: <String, Object>{},
        ).then((LaunchResult result) {
          launchResult = result;
        });

        // Elapse duration for process timeout.
        time.flushMicrotasks();
        time.elapse(const Duration(minutes: 1));

        // Elapse duration for overall process timer.
        time.flushMicrotasks();
        time.elapse(const Duration(minutes: 5));

        time.flushTimers();
      });

      expect(launchResult?.started, true);
      expect(processManager.hasRemainingExpectations, false);
    }, overrides: <Type, Generator>{
      ProcessManager: () => processManager,
      FileSystem: () => fileSystem,
      Logger: () => logger,
      Platform: () => macPlatform,
      XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
      Xcode: () => mockXcode,
    });

    testUsingContext('with concurrent build failures', () async {
      final IOSDevice iosDevice = setUpIOSDevice(
        fileSystem: fileSystem,
        processManager: processManager,
        logger: logger,
        artifacts: artifacts,
      );
      setUpIOSProject(fileSystem);
      final FlutterProject flutterProject = FlutterProject.fromDirectory(fileSystem.currentDirectory);
      final BuildableIOSApp buildableIOSApp = BuildableIOSApp(flutterProject.ios, 'flutter', 'My Super Awesome App.app');

      processManager.addCommand(FakeCommand(command: _xattrArgs(flutterProject)));
      // The first xcrun call should fail with a
      // concurrent build exception.
      processManager.addCommand(
        const FakeCommand(
          command: kRunReleaseArgs,
          exitCode: 1,
          stdout: kConcurrentBuildErrorMessage,
        ));
      processManager.addCommand(const FakeCommand(command: kRunReleaseArgs));
      processManager.addCommand(
        const FakeCommand(
          command: <String>[...kRunReleaseArgs, '-showBuildSettings'],
          exitCode: 0,
        ));
      processManager.addCommand(FakeCommand(
        command: <String>[
          iosDeployPath,
          '--id',
          '123',
          '--bundle',
          'build/ios/iphoneos/My Super Awesome App.app',
          '--no-wifi',
          '--justlaunch',
          '--args',
          const <String>[
            '--enable-dart-profiling',
            '--disable-service-auth-codes',
          ].join(' ')
        ])
      );

      await FakeAsync().run((FakeAsync time) async {
        final LaunchResult launchResult = await iosDevice.startApp(
          buildableIOSApp,
          debuggingOptions: DebuggingOptions.disabled(BuildInfo.release),
          platformArgs: <String, Object>{},
        );
        time.elapse(const Duration(seconds: 2));

        expect(logger.statusText,
          contains('Xcode build failed due to concurrent builds, will retry in 2 seconds'));
        expect(launchResult.started, true);
        expect(processManager.hasRemainingExpectations, false);
      });
    }, overrides: <Type, Generator>{
      ProcessManager: () => processManager,
      FileSystem: () => fileSystem,
      Logger: () => logger,
      Platform: () => macPlatform,
      XcodeProjectInterpreter: () => mockXcodeProjectInterpreter,
      Xcode: () => mockXcode,
    }, skip: true); // TODO(jonahwilliams): clean up with https://github.com/flutter/flutter/issues/60675
  });
}

void setUpIOSProject(FileSystem fileSystem) {
  fileSystem.file('pubspec.yaml').createSync();
  fileSystem.file('.packages').writeAsStringSync('\n');
  fileSystem.directory('ios').createSync();
  fileSystem.directory('ios/Runner.xcworkspace').createSync();
  fileSystem.file('ios/Runner.xcodeproj/project.pbxproj').createSync(recursive: true);
  // This is the expected output directory.
  fileSystem.directory('build/ios/iphoneos/My Super Awesome App.app').createSync(recursive: true);
}

IOSDevice setUpIOSDevice({
  String sdkVersion = '13.0.1',
  FileSystem fileSystem,
  Logger logger,
  ProcessManager processManager,
  Artifacts artifacts,
}) {
  artifacts ??= Artifacts.test();
  final Cache cache = Cache.test(
    artifacts: <ArtifactSet>[
      FakeDyldEnvironmentArtifact(),
    ],
  );

  logger ??= BufferLogger.test();
  return IOSDevice('123',
    name: 'iPhone 1',
    sdkVersion: sdkVersion,
    fileSystem: fileSystem ?? MemoryFileSystem.test(),
    platform: macPlatform,
    iProxy: IProxy.test(logger: logger, processManager: processManager ?? FakeProcessManager.any()),
    logger: logger,
    iosDeploy: IOSDeploy(
      logger: logger,
      platform: macPlatform,
      processManager: processManager ?? FakeProcessManager.any(),
      artifacts: artifacts,
      cache: cache,
    ),
    iMobileDevice: IMobileDevice(
      logger: logger,
      processManager: processManager ?? FakeProcessManager.any(),
      artifacts: artifacts,
      cache: cache,
    ),
    cpuArchitecture: DarwinArch.arm64,
    interfaceType: IOSDeviceInterface.usb,
  );
}

class MockXcode extends Mock implements Xcode {}
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
class MockVmService extends Mock implements VmService {}
