// Copyright 2013 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 'dart:convert';

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_plugin_tools/src/common/core.dart';
import 'package:flutter_plugin_tools/src/common/plugin_utils.dart';
import 'package:flutter_plugin_tools/src/xctest_command.dart';
import 'package:test/test.dart';

import 'mocks.dart';
import 'util.dart';

// Note: This uses `dynamic` deliberately, and should not be updated to Object,
// in order to ensure that the code correctly handles this return type from
// JSON decoding.
final Map<String, dynamic> _kDeviceListMap = <String, dynamic>{
  'runtimes': <Map<String, dynamic>>[
    <String, dynamic>{
      'bundlePath':
          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime',
      'buildversion': '17A577',
      'runtimeRoot':
          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.0.simruntime/Contents/Resources/RuntimeRoot',
      'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-0',
      'version': '13.0',
      'isAvailable': true,
      'name': 'iOS 13.0'
    },
    <String, dynamic>{
      'bundlePath':
          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime',
      'buildversion': '17L255',
      'runtimeRoot':
          '/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 13.4.simruntime/Contents/Resources/RuntimeRoot',
      'identifier': 'com.apple.CoreSimulator.SimRuntime.iOS-13-4',
      'version': '13.4',
      'isAvailable': true,
      'name': 'iOS 13.4'
    },
    <String, dynamic>{
      'bundlePath':
          '/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime',
      'buildversion': '17T531',
      'runtimeRoot':
          '/Applications/Xcode_11_7.app/Contents/Developer/Platforms/WatchOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/watchOS.simruntime/Contents/Resources/RuntimeRoot',
      'identifier': 'com.apple.CoreSimulator.SimRuntime.watchOS-6-2',
      'version': '6.2.1',
      'isAvailable': true,
      'name': 'watchOS 6.2'
    }
  ],
  'devices': <String, dynamic>{
    'com.apple.CoreSimulator.SimRuntime.iOS-13-4': <Map<String, dynamic>>[
      <String, dynamic>{
        'dataPath':
            '/Users/xxx/Library/Developer/CoreSimulator/Devices/2706BBEB-1E01-403E-A8E9-70E8E5A24774/data',
        'logPath':
            '/Users/xxx/Library/Logs/CoreSimulator/2706BBEB-1E01-403E-A8E9-70E8E5A24774',
        'udid': '2706BBEB-1E01-403E-A8E9-70E8E5A24774',
        'isAvailable': true,
        'deviceTypeIdentifier':
            'com.apple.CoreSimulator.SimDeviceType.iPhone-8',
        'state': 'Shutdown',
        'name': 'iPhone 8'
      },
      <String, dynamic>{
        'dataPath':
            '/Users/xxx/Library/Developer/CoreSimulator/Devices/1E76A0FD-38AC-4537-A989-EA639D7D012A/data',
        'logPath':
            '/Users/xxx/Library/Logs/CoreSimulator/1E76A0FD-38AC-4537-A989-EA639D7D012A',
        'udid': '1E76A0FD-38AC-4537-A989-EA639D7D012A',
        'isAvailable': true,
        'deviceTypeIdentifier':
            'com.apple.CoreSimulator.SimDeviceType.iPhone-8-Plus',
        'state': 'Shutdown',
        'name': 'iPhone 8 Plus'
      }
    ]
  }
};

void main() {
  const String _kDestination = '--ios-destination';

  group('test xctest_command', () {
    late FileSystem fileSystem;
    late Directory packagesDir;
    late CommandRunner<void> runner;
    late RecordingProcessRunner processRunner;

    setUp(() {
      fileSystem = MemoryFileSystem();
      packagesDir = createPackagesDirectory(fileSystem: fileSystem);
      processRunner = RecordingProcessRunner();
      final XCTestCommand command =
          XCTestCommand(packagesDir, processRunner: processRunner);

      runner = CommandRunner<void>('xctest_command', 'Test for xctest_command');
      runner.addCommand(command);
    });

    test('Fails if no platforms are provided', () async {
      expect(
        () => runner.run(<String>['xctest']),
        throwsA(isA<ToolExit>()),
      );
    });

    group('iOS', () {
      test('skip if iOS is not supported', () async {
        createFakePlugin('plugin', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformMacos: PlatformSupport.inline,
        });

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        final List<String> output = await runCapturingPrint(runner,
            <String>['xctest', '--ios', _kDestination, 'foo_destination']);
        expect(
            output,
            contains(
                contains('iOS is not implemented by this plugin package.')));
        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
      });

      test('skip if iOS is implemented in a federated package', () async {
        createFakePlugin('plugin', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformIos: PlatformSupport.federated
        });

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        final List<String> output = await runCapturingPrint(runner,
            <String>['xctest', '--ios', _kDestination, 'foo_destination']);
        expect(
            output,
            contains(
                contains('iOS is not implemented by this plugin package.')));
        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
      });

      test('running with correct destination, exclude 1 plugin', () async {
        createFakePlugin('plugin1', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformIos: PlatformSupport.inline
        });
        final Directory pluginDirectory2 =
            createFakePlugin('plugin2', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformIos: PlatformSupport.inline
        });

        final Directory pluginExampleDirectory2 =
            pluginDirectory2.childDirectory('example');

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        processRunner.resultStdout =
            '{"project":{"targets":["bar_scheme", "foo_scheme"]}}';
        final List<String> output = await runCapturingPrint(runner, <String>[
          'xctest',
          '--ios',
          _kDestination,
          'foo_destination',
          '--exclude',
          'plugin1'
        ]);

        expect(output, isNot(contains(contains('Running for plugin1'))));
        expect(output, contains(contains('Running for plugin2')));
        expect(
            output,
            contains(
                contains('Successfully ran iOS xctest for plugin2/example')));

        expect(
            processRunner.recordedCalls,
            orderedEquals(<ProcessCall>[
              ProcessCall(
                  'xcrun',
                  const <String>[
                    'xcodebuild',
                    'test',
                    'analyze',
                    '-workspace',
                    'ios/Runner.xcworkspace',
                    '-configuration',
                    'Debug',
                    '-scheme',
                    'Runner',
                    '-destination',
                    'foo_destination',
                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
                  ],
                  pluginExampleDirectory2.path),
            ]));
      });

      test('Not specifying --ios-destination assigns an available simulator',
          () async {
        final Directory pluginDirectory =
            createFakePlugin('plugin', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformIos: PlatformSupport.inline
        });

        final Directory pluginExampleDirectory =
            pluginDirectory.childDirectory('example');

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        final Map<String, dynamic> schemeCommandResult = <String, dynamic>{
          'project': <String, dynamic>{
            'targets': <String>['bar_scheme', 'foo_scheme']
          }
        };
        // For simplicity of the test, we combine all the mock results into a single mock result, each internal command
        // will get this result and they should still be able to parse them correctly.
        processRunner.resultStdout =
            jsonEncode(schemeCommandResult..addAll(_kDeviceListMap));
        await runner.run(<String>['xctest', '--ios']);

        expect(
            processRunner.recordedCalls,
            orderedEquals(<ProcessCall>[
              const ProcessCall(
                  'xcrun', <String>['simctl', 'list', '--json'], null),
              ProcessCall(
                  'xcrun',
                  const <String>[
                    'xcodebuild',
                    'test',
                    'analyze',
                    '-workspace',
                    'ios/Runner.xcworkspace',
                    '-configuration',
                    'Debug',
                    '-scheme',
                    'Runner',
                    '-destination',
                    'id=1E76A0FD-38AC-4537-A989-EA639D7D012A',
                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
                  ],
                  pluginExampleDirectory.path),
            ]));
      });
    });

    group('macOS', () {
      test('skip if macOS is not supported', () async {
        createFakePlugin(
          'plugin',
          packagesDir,
          extraFiles: <String>[
            'example/test',
          ],
        );

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        final List<String> output = await runCapturingPrint(runner,
            <String>['xctest', '--macos', _kDestination, 'foo_destination']);
        expect(
            output,
            contains(
                contains('macOS is not implemented by this plugin package.')));
        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
      });

      test('skip if macOS is implemented in a federated package', () async {
        createFakePlugin('plugin', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformMacos: PlatformSupport.federated,
        });

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        final List<String> output = await runCapturingPrint(runner,
            <String>['xctest', '--macos', _kDestination, 'foo_destination']);
        expect(
            output,
            contains(
                contains('macOS is not implemented by this plugin package.')));
        expect(processRunner.recordedCalls, orderedEquals(<ProcessCall>[]));
      });

      test('runs for macOS plugin', () async {
        final Directory pluginDirectory1 =
            createFakePlugin('plugin', packagesDir, extraFiles: <String>[
          'example/test',
        ], platformSupport: <String, PlatformSupport>{
          kPlatformMacos: PlatformSupport.inline,
        });

        final Directory pluginExampleDirectory =
            pluginDirectory1.childDirectory('example');

        final MockProcess mockProcess = MockProcess();
        mockProcess.exitCodeCompleter.complete(0);
        processRunner.processToReturn = mockProcess;
        processRunner.resultStdout =
            '{"project":{"targets":["bar_scheme", "foo_scheme"]}}';
        final List<String> output = await runCapturingPrint(runner, <String>[
          'xctest',
          '--macos',
        ]);

        expect(
            output,
            contains(
                contains('Successfully ran macOS xctest for plugin/example')));

        expect(
            processRunner.recordedCalls,
            orderedEquals(<ProcessCall>[
              ProcessCall(
                  'xcrun',
                  const <String>[
                    'xcodebuild',
                    'test',
                    'analyze',
                    '-workspace',
                    'macos/Runner.xcworkspace',
                    '-configuration',
                    'Debug',
                    '-scheme',
                    'Runner',
                    'GCC_TREAT_WARNINGS_AS_ERRORS=YES',
                  ],
                  pluginExampleDirectory.path),
            ]));
      });
    });
  });
}
