// 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:file_testing/file_testing.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/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/ios.dart';
import 'package:flutter_tools/src/convert.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';

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

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

const List<String> _kSharedConfig = <String>[
  '-dynamiclib',
  '-miphoneos-version-min=11.0',
  '-Xlinker',
  '-rpath',
  '-Xlinker',
  '@executable_path/Frameworks',
  '-Xlinker',
  '-rpath',
  '-Xlinker',
  '@loader_path/Frameworks',
  '-install_name',
  '@rpath/App.framework/App',
  '-isysroot',
  'path/to/iPhoneOS.sdk',
];

void main() {
  late Environment environment;
  late FileSystem fileSystem;
  late FakeProcessManager processManager;
  late Artifacts artifacts;
  late BufferLogger logger;
  late TestUsage usage;

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    processManager = FakeProcessManager.empty();
    logger = BufferLogger.test();
    artifacts = Artifacts.test();
    usage = TestUsage();
    environment = Environment.test(
      fileSystem.currentDirectory,
      defines: <String, String>{
        kTargetPlatform: 'ios',
      },
      inputs: <String, String>{},
      processManager: processManager,
      artifacts: artifacts,
      logger: logger,
      fileSystem: fileSystem,
      engineVersion: '2',
      usage: usage,
    );
  });

  testWithoutContext('iOS AOT targets has analyticsName', () {
    expect(const AotAssemblyRelease().analyticsName, 'ios_aot');
    expect(const AotAssemblyProfile().analyticsName, 'ios_aot');
  });

  testUsingContext('DebugUniversalFramework creates simulator binary', () async {
    environment.defines[kIosArchs] = 'x86_64';
    environment.defines[kSdkRoot] = 'path/to/iPhoneSimulator.sdk';
    final String appFrameworkPath = environment.buildDir.childDirectory('App.framework').childFile('App').path;
    processManager.addCommands(<FakeCommand>[
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
        '-arch',
        'x86_64',
        fileSystem.path.absolute(fileSystem.path.join(
            '.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
        '-dynamiclib',
        '-miphonesimulator-version-min=11.0',
        '-Xlinker',
        '-rpath',
        '-Xlinker',
        '@executable_path/Frameworks',
        '-Xlinker',
        '-rpath',
        '-Xlinker',
        '@loader_path/Frameworks',
        '-install_name',
        '@rpath/App.framework/App',
        '-isysroot',
        'path/to/iPhoneSimulator.sdk',
        '-o',
        appFrameworkPath,
      ]),
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        '-',
        '--timestamp=none',
        appFrameworkPath,
      ]),
    ]);

    await const DebugUniversalFramework().build(environment);
    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('DebugUniversalFramework creates expected binary with arm64 only arch', () async {
    environment.defines[kIosArchs] = 'arm64';
    environment.defines[kSdkRoot] = 'path/to/iPhoneOS.sdk';
    final String appFrameworkPath = environment.buildDir.childDirectory('App.framework').childFile('App').path;
    processManager.addCommands(<FakeCommand>[
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
        // iphone only gets 64 bit arch based on kIosArchs
        '-arch',
        'arm64',
        fileSystem.path.absolute(fileSystem.path.join(
            '.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
        ..._kSharedConfig,
        '-o',
        appFrameworkPath,
      ]),
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        '-',
        '--timestamp=none',
        appFrameworkPath,
      ]),
    ]);

    await const DebugUniversalFramework().build(environment);
    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('DebugIosApplicationBundle', () async {
    environment.defines[kBundleSkSLPath] = 'bundle.sksl';
    environment.defines[kBuildMode] = 'debug';
    environment.defines[kCodesignIdentity] = 'ABC123';
    // Precompiled dart data

    fileSystem.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
      .createSync();
    fileSystem.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
      .createSync();
    // Project info
    fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello');
    fileSystem.file('.packages').writeAsStringSync('\n');
    // Plist file
    fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
      .createSync(recursive: true);
    // App kernel
    environment.buildDir.childFile('app.dill').createSync(recursive: true);
    // Stub framework
    environment.buildDir
        .childDirectory('App.framework')
      .childFile('App')
      .createSync(recursive: true);
    // sksl bundle
    fileSystem.file('bundle.sksl').writeAsStringSync(json.encode(
      <String, Object>{
        'engineRevision': '2',
        'platform': 'ios',
        'data': <String, Object>{
          'A': 'B',
        },
      },
    ));

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
    processManager.addCommand(
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        'ABC123',
        '--timestamp=none',
        frameworkDirectoryBinary.path,
      ]),
    );

    await const DebugIosApplicationBundle().build(environment);
    expect(processManager, hasNoRemainingExpectations);

    expect(frameworkDirectoryBinary, exists);
    expect(frameworkDirectory.childFile('Info.plist'), exists);

    final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets');
    expect(assetDirectory.childFile('kernel_blob.bin'), exists);
    expect(assetDirectory.childFile('AssetManifest.json'), exists);
    expect(assetDirectory.childFile('vm_snapshot_data'), exists);
    expect(assetDirectory.childFile('isolate_snapshot_data'), exists);
    expect(assetDirectory.childFile('io.flutter.shaders.json'), exists);
    expect(assetDirectory.childFile('io.flutter.shaders.json').readAsStringSync(), '{"data":{"A":"B"}}');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('DebugIosApplicationBundle with impeller and shader compilation', () async {
    // Create impellerc to work around fallback detection logic.
    fileSystem.file(artifacts.getHostArtifact(HostArtifact.impellerc)).createSync(recursive: true);

    environment.defines[kBuildMode] = 'debug';
    environment.defines[kCodesignIdentity] = 'ABC123';
    // Precompiled dart data

    fileSystem.file(artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
      .createSync();
    fileSystem.file(artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
      .createSync();
    // Project info
    fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello\nflutter:\n  shaders:\n    - shader.glsl');
    fileSystem.file('.packages').writeAsStringSync('\n');
    // Plist file
    fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
      .createSync(recursive: true);
    // Shader file
    fileSystem.file('shader.glsl').writeAsStringSync('test');
    // App kernel
    environment.buildDir.childFile('app.dill').createSync(recursive: true);
    // Stub framework
    environment.buildDir
        .childDirectory('App.framework')
      .childFile('App')
      .createSync(recursive: true);

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
    processManager.addCommands(<FakeCommand>[
      const FakeCommand(command: <String>[
        'HostArtifact.impellerc',
        '--runtime-stage-metal',
        '--iplr',
        '--sl=/App.framework/flutter_assets/shader.glsl',
        '--spirv=/App.framework/flutter_assets/shader.glsl.spirv',
        '--input=/shader.glsl',
        '--input-type=frag',
        '--include=/',
        '--include=/./shader_lib',
      ]),
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        'ABC123',
        '--timestamp=none',
        frameworkDirectoryBinary.path,
      ]),
    ]);

    await const DebugIosApplicationBundle().build(environment);
    expect(processManager, hasNoRemainingExpectations);

    expect(frameworkDirectoryBinary, exists);
    expect(frameworkDirectory.childFile('Info.plist'), exists);

    final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets');
    expect(assetDirectory.childFile('kernel_blob.bin'), exists);
    expect(assetDirectory.childFile('AssetManifest.json'), exists);
    expect(assetDirectory.childFile('vm_snapshot_data'), exists);
    expect(assetDirectory.childFile('isolate_snapshot_data'), exists);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('ReleaseIosApplicationBundle build', () async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[kCodesignIdentity] = 'ABC123';
    environment.defines[kXcodeAction] = 'build';

    // Project info
    fileSystem.file('pubspec.yaml').writeAsStringSync('name: hello');
    fileSystem.file('.packages').writeAsStringSync('\n');
    // Plist file
    fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
      .createSync(recursive: true);

    // Real framework
    environment.buildDir
      .childDirectory('App.framework')
      .childFile('App')
      .createSync(recursive: true);

    // Input dSYM
    environment.buildDir
      .childDirectory('App.framework.dSYM')
      .childDirectory('Contents')
      .childDirectory('Resources')
      .childDirectory('DWARF')
      .childFile('App')
      .createSync(recursive: true);

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
    processManager.addCommand(
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        'ABC123',
        frameworkDirectoryBinary.path,
      ]),
    );

    await const ReleaseIosApplicationBundle().build(environment);
    expect(processManager, hasNoRemainingExpectations);

    expect(frameworkDirectoryBinary, exists);
    expect(frameworkDirectory.childFile('Info.plist'), exists);
    expect(environment.outputDir
      .childDirectory('App.framework.dSYM')
      .childDirectory('Contents')
      .childDirectory('Resources')
      .childDirectory('DWARF')
      .childFile('App'), exists);

    final Directory assetDirectory = frameworkDirectory.childDirectory('flutter_assets');
    expect(assetDirectory.childFile('kernel_blob.bin'), isNot(exists));
    expect(assetDirectory.childFile('AssetManifest.json'), exists);
    expect(assetDirectory.childFile('vm_snapshot_data'), isNot(exists));
    expect(assetDirectory.childFile('isolate_snapshot_data'), isNot(exists));
    expect(usage.events, isEmpty);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('ReleaseIosApplicationBundle sends archive success event', () async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[kXcodeAction] = 'install';

    fileSystem.file(fileSystem.path.join('ios', 'Flutter', 'AppFrameworkInfo.plist'))
        .createSync(recursive: true);

    environment.buildDir
        .childDirectory('App.framework')
        .childFile('App')
        .createSync(recursive: true);

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    final File frameworkDirectoryBinary = frameworkDirectory.childFile('App');
    processManager.addCommand(
      FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        '-',
        frameworkDirectoryBinary.path,
      ]),
    );

    await const ReleaseIosApplicationBundle().build(environment);
    expect(usage.events, contains(const TestUsageEvent('assemble', 'ios-archive', label: 'success')));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('ReleaseIosApplicationBundle sends archive fail event', () async {
    environment.defines[kBuildMode] = 'release';
    environment.defines[kXcodeAction] = 'install';

    // Throws because the project files are not set up.
    await expectLater(() => const ReleaseIosApplicationBundle().build(environment),
        throwsA(const TypeMatcher<FileSystemException>()));
    expect(usage.events, contains(const TestUsageEvent('assemble', 'ios-archive', label: 'fail')));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('AotAssemblyRelease throws exception if asked to build for simulator', () async {
    final FileSystem fileSystem = MemoryFileSystem.test();
    final Environment environment = Environment.test(
      fileSystem.currentDirectory,
      defines: <String, String>{
        kTargetPlatform: 'ios',
        kSdkRoot: 'path/to/iPhoneSimulator.sdk',
        kBuildMode: 'release',
        kIosArchs: 'x86_64',
      },
      processManager: processManager,
      artifacts: artifacts,
      logger: logger,
      fileSystem: fileSystem,
    );

    expect(const AotAssemblyRelease().build(environment), throwsA(isException
      .having(
        (Exception exception) => exception.toString(),
        'description',
        contains('release/profile builds are only supported for physical devices.'),
      )
    ));
    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  testUsingContext('AotAssemblyRelease throws exception if sdk root is missing', () async {
    final FileSystem fileSystem = MemoryFileSystem.test();
    final Environment environment = Environment.test(
      fileSystem.currentDirectory,
      defines: <String, String>{
        kTargetPlatform: 'ios',
      },
      processManager: processManager,
      artifacts: artifacts,
      logger: logger,
      fileSystem: fileSystem,
    );
    environment.defines[kBuildMode] = 'release';
    environment.defines[kIosArchs] = 'x86_64';

    expect(const AotAssemblyRelease().build(environment), throwsA(isException.having(
      (Exception exception) => exception.toString(),
      'description',
      contains('required define SdkRoot but it was not provided'),
    )));
    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
    Platform: () => macPlatform,
  });

  group('copies Flutter.framework', () {
    late Directory outputDir;
    late File binary;
    late FakeCommand copyPhysicalFrameworkCommand;
    late FakeCommand lipoCommandNonFatResult;
    late FakeCommand lipoVerifyArm64Command;
    late FakeCommand adHocCodesignCommand;

    setUp(() {
      final FileSystem fileSystem = MemoryFileSystem.test();
      outputDir = fileSystem.directory('output');
      binary = outputDir.childDirectory('Flutter.framework').childFile('Flutter');
      copyPhysicalFrameworkCommand = FakeCommand(command: <String>[
        'rsync',
        '-av',
        '--delete',
        '--filter',
        '- .DS_Store/',
        'Artifact.flutterFramework.TargetPlatform.ios.debug.EnvironmentType.physical',
        outputDir.path,
      ]);

      lipoCommandNonFatResult = FakeCommand(command: <String>[
        'lipo',
        '-info',
        binary.path,
      ], stdout: 'Non-fat file:');

      lipoVerifyArm64Command = FakeCommand(command: <String>[
        'lipo',
        binary.path,
        '-verify_arch',
        'arm64',
      ]);

      adHocCodesignCommand = FakeCommand(command: <String>[
        'codesign',
        '--force',
        '--sign',
        '-',
        '--timestamp=none',
        binary.path,
      ]);
    });

    testWithoutContext('iphonesimulator', () async {
      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'x86_64',
          kSdkRoot: 'path/to/iPhoneSimulator.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        FakeCommand(command: <String>[
          'rsync',
          '-av',
          '--delete',
          '--filter',
          '- .DS_Store/',
          'Artifact.flutterFramework.TargetPlatform.ios.debug.EnvironmentType.simulator',
          outputDir.path,
          ],
          onRun: () => binary.createSync(recursive: true),
        ),
        lipoCommandNonFatResult,
        FakeCommand(command: <String>[
          'lipo',
          binary.path,
          '-verify_arch',
          'x86_64',
        ]),
        adHocCodesignCommand,
      ]);
      await const DebugUnpackIOS().build(environment);

      expect(logger.traceText, contains('Skipping lipo for non-fat file output/Flutter.framework/Flutter'));
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('fails when frameworks missing', () async {
      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );
      processManager.addCommand(copyPhysicalFrameworkCommand);
      await expectLater(
        const DebugUnpackIOS().build(environment),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('Flutter.framework/Flutter does not exist, cannot thin'),
        )));
    });

    testWithoutContext('fails when requested archs missing from framework', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64 armv7',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        FakeCommand(command: <String>[
          'lipo',
          '-info',
          binary.path,
        ], stdout: 'Architectures in the fat file:'),
        FakeCommand(command: <String>[
          'lipo',
          binary.path,
          '-verify_arch',
          'arm64',
          'armv7',
        ], exitCode: 1),
      ]);

      await expectLater(
        const DebugUnpackIOS().build(environment),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('does not contain arm64 armv7. Running lipo -info:\nArchitectures in the fat file:'),
        )),
      );
    });

    testWithoutContext('fails when lipo extract fails', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64 armv7',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        FakeCommand(command: <String>[
          'lipo',
          '-info',
          binary.path,
        ], stdout: 'Architectures in the fat file:'),
        FakeCommand(command: <String>[
          'lipo',
          binary.path,
          '-verify_arch',
          'arm64',
          'armv7',
        ]),
        FakeCommand(command: <String>[
          'lipo',
          '-output',
          binary.path,
          '-extract',
          'arm64',
          '-extract',
          'armv7',
          binary.path,
        ], exitCode: 1,
        stderr: 'lipo error'),
      ]);

      await expectLater(
        const DebugUnpackIOS().build(environment),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('Failed to extract arm64 armv7 for output/Flutter.framework/Flutter.\nlipo error\nRunning lipo -info:\nArchitectures in the fat file:'),
        )),
      );
    });

    testWithoutContext('skips thin framework', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        lipoCommandNonFatResult,
        lipoVerifyArm64Command,
        adHocCodesignCommand,
      ]);
      await const DebugUnpackIOS().build(environment);

      expect(logger.traceText, contains('Skipping lipo for non-fat file output/Flutter.framework/Flutter'));

      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('thins fat framework', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64 armv7',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        FakeCommand(command: <String>[
          'lipo',
          '-info',
          binary.path,
        ], stdout: 'Architectures in the fat file:'),
        FakeCommand(command: <String>[
          'lipo',
          binary.path,
          '-verify_arch',
          'arm64',
          'armv7',
        ]),
        FakeCommand(command: <String>[
          'lipo',
          '-output',
          binary.path,
          '-extract',
          'arm64',
          '-extract',
          'armv7',
          binary.path,
        ]),
        adHocCodesignCommand,
      ]);

      await const DebugUnpackIOS().build(environment);
      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('fails when bitcode strip fails', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        FakeCommand(command: <String>[
          'rsync',
          '-av',
          '--delete',
          '--filter',
          '- .DS_Store/',
          'Artifact.flutterFramework.TargetPlatform.ios.release.EnvironmentType.physical',
          outputDir.path,
        ]),
        lipoCommandNonFatResult,
        lipoVerifyArm64Command,
        FakeCommand(command: <String>[
          'xcrun',
          'bitcode_strip',
          binary.path,
          '-r',
          '-o',
          binary.path,
        ], exitCode: 1, stderr: 'bitcode_strip error'),
      ]);

      await expectLater(
        const ReleaseUnpackIOS().build(environment),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('Failed to strip bitcode for output/Flutter.framework/Flutter.\nbitcode_strip error'),
        )),
      );

      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('strips framework', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        lipoCommandNonFatResult,
        lipoVerifyArm64Command,
        adHocCodesignCommand,
      ]);
      await const DebugUnpackIOS().build(environment);

      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('fails when codesign fails', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
          kCodesignIdentity: 'ABC123',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        lipoCommandNonFatResult,
        lipoVerifyArm64Command,
        FakeCommand(command: <String>[
            'codesign',
            '--force',
            '--sign',
            'ABC123',
            '--timestamp=none',
            binary.path,
          ],
          exitCode: 1,
          stderr: 'codesign error',
          stdout: 'codesign info',
        ),
      ]);

      await expectLater(
        const DebugUnpackIOS().build(environment),
        throwsA(isException.having(
          (Exception exception) => exception.toString(),
          'description',
          contains('Failed to codesign output/Flutter.framework/Flutter with identity ABC123.\ncodesign info\ncodesign error'),
        )),
      );

      expect(processManager, hasNoRemainingExpectations);
    });

    testWithoutContext('codesigns framework', () async {
      binary.createSync(recursive: true);

      final Environment environment = Environment.test(
        fileSystem.currentDirectory,
        processManager: processManager,
        artifacts: artifacts,
        logger: logger,
        fileSystem: fileSystem,
        outputDir: outputDir,
        defines: <String, String>{
          kIosArchs: 'arm64',
          kSdkRoot: 'path/to/iPhoneOS.sdk',
          kCodesignIdentity: 'ABC123',
        },
      );

      processManager.addCommands(<FakeCommand>[
        copyPhysicalFrameworkCommand,
        lipoCommandNonFatResult,
        lipoVerifyArm64Command,
        FakeCommand(command: <String>[
          'codesign',
          '--force',
          '--sign',
          'ABC123',
          '--timestamp=none',
          binary.path,
        ]),
      ]);
      await const DebugUnpackIOS().build(environment);

      expect(processManager, hasNoRemainingExpectations);
    });
  });
}
