// 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.

// @dart = 2.8

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

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

void main() {
  Environment environment;
  FileSystem fileSystem;
  Artifacts artifacts;
  FakeProcessManager processManager;
  File binary;
  BufferLogger logger;
  FakeCommand copyFrameworkCommand;
  FakeCommand lipoInfoNonFatCommand;
  FakeCommand lipoInfoFatCommand;
  FakeCommand lipoVerifyX86_64Command;

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

    binary = environment.outputDir
        .childDirectory('FlutterMacOS.framework')
        .childFile('FlutterMacOS');

    copyFrameworkCommand = FakeCommand(
      command: <String>[
        'rsync',
        '-av',
        '--delete',
        '--filter',
        '- .DS_Store/',
        'Artifact.flutterMacOSFramework.debug',
        environment.outputDir.path,
      ],
    );

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

    lipoInfoFatCommand = FakeCommand(command: <String>[
      'lipo',
      '-info',
      binary.path,
    ], stdout: 'Architectures in the fat file:');

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

  testUsingContext('Copies files to correct cache directory', () async {
    binary.createSync(recursive: true);
    processManager.addCommands(<FakeCommand>[
      copyFrameworkCommand,
      lipoInfoNonFatCommand,
      lipoVerifyX86_64Command,
    ]);

    await const DebugUnpackMacOS().build(environment);

    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('thinning fails when framework missing', () async {
    processManager.addCommand(copyFrameworkCommand);
    await expectLater(
      const DebugUnpackMacOS().build(environment),
      throwsA(isException.having(
        (Exception exception) => exception.toString(),
        'description',
        contains('FlutterMacOS.framework/FlutterMacOS does not exist, cannot thin'),
      )),
    );
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('lipo fails when arch missing from framework', () async {
    environment.defines[kDarwinArchs] = 'arm64 x86_64';
    binary.createSync(recursive: true);
    processManager.addCommands(<FakeCommand>[
      copyFrameworkCommand,
      lipoInfoFatCommand,
      FakeCommand(command: <String>[
        'lipo',
        binary.path,
        '-verify_arch',
        'arm64',
        'x86_64',
      ], exitCode: 1),
    ]);

    await expectLater(
      const DebugUnpackMacOS().build(environment),
      throwsA(isException.having(
        (Exception exception) => exception.toString(),
        'description',
        contains('does not contain arm64 x86_64. Running lipo -info:\nArchitectures in the fat file:'),
      )),
    );
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('skips thins framework', () async {
    binary.createSync(recursive: true);
    processManager.addCommands(<FakeCommand>[
      copyFrameworkCommand,
      lipoInfoNonFatCommand,
      lipoVerifyX86_64Command,
    ]);

    await const DebugUnpackMacOS().build(environment);

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

  testUsingContext('thins fat framework', () async {
    binary.createSync(recursive: true);
    processManager.addCommands(<FakeCommand>[
      copyFrameworkCommand,
      lipoInfoFatCommand,
      lipoVerifyX86_64Command,
      FakeCommand(command: <String>[
          'lipo',
          '-output',
          binary.path,
          '-extract',
          'x86_64',
          binary.path,
      ]),
    ]);

    await const DebugUnpackMacOS().build(environment);

    expect(processManager, hasNoRemainingExpectations);
  });

  testUsingContext('debug macOS application fails if App.framework missing', () async {
    fileSystem.directory(
      artifacts.getArtifactPath(
        Artifact.flutterMacOSFramework,
        mode: BuildMode.debug,
      ))
      .createSync();
    final String inputKernel = fileSystem.path.join(environment.buildDir.path, 'app.dill');
    fileSystem.file(inputKernel)
      ..createSync(recursive: true)
      ..writeAsStringSync('testing');

    expect(() async => const DebugMacOSBundleFlutterAssets().build(environment),
        throwsException);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('debug macOS application creates correctly structured framework', () async {
    fileSystem.directory(
      artifacts.getArtifactPath(
        Artifact.flutterMacOSFramework,
        mode: BuildMode.debug,
      ))
      .createSync();
    environment.defines[kBundleSkSLPath] = 'bundle.sksl';
    fileSystem.file(
      artifacts.getArtifactPath(
        Artifact.vmSnapshotData,
        platform: TargetPlatform.darwin,
        mode: BuildMode.debug,
      )).createSync(recursive: true);
    fileSystem.file(
      artifacts.getArtifactPath(
        Artifact.isolateSnapshotData,
        platform: TargetPlatform.darwin,
        mode: BuildMode.debug,
      )).createSync(recursive: true);
    fileSystem.file('${environment.buildDir.path}/App.framework/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 String inputKernel = '${environment.buildDir.path}/app.dill';
    fileSystem.file(inputKernel)
      ..createSync(recursive: true)
      ..writeAsStringSync('testing');

    await const DebugMacOSBundleFlutterAssets().build(environment);

    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/kernel_blob.bin').readAsStringSync(),
      'testing',
    );
    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/Info.plist').readAsStringSync(),
      contains('io.flutter.flutter.app'),
    );
    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/vm_snapshot_data'),
      exists,
    );
    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/isolate_snapshot_data'),
      exists,
    );

    final File skslFile = fileSystem.file('App.framework/Versions/A/Resources/flutter_assets/io.flutter.shaders.json');

    expect(skslFile, exists);
    expect(skslFile.readAsStringSync(), '{"data":{"A":"B"}}');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('release/profile macOS application has no blob or precompiled runtime', () async {
    fileSystem.file('bin/cache/artifacts/engine/darwin-x64/vm_isolate_snapshot.bin')
      .createSync(recursive: true);
    fileSystem.file('bin/cache/artifacts/engine/darwin-x64/isolate_snapshot.bin')
      .createSync(recursive: true);
    fileSystem.file('${environment.buildDir.path}/App.framework/App')
      .createSync(recursive: true);

    await const ProfileMacOSBundleFlutterAssets().build(environment..defines[kBuildMode] = 'profile');

    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/kernel_blob.bin'),
      isNot(exists),
    );
    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/vm_snapshot_data'),
      isNot(exists),
    );
    expect(fileSystem.file(
      'App.framework/Versions/A/Resources/flutter_assets/isolate_snapshot_data'),
      isNot(exists),
    );
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('release/profile macOS application updates when App.framework updates', () async {
    fileSystem.file('bin/cache/artifacts/engine/darwin-x64/vm_isolate_snapshot.bin')
      .createSync(recursive: true);
    fileSystem.file('bin/cache/artifacts/engine/darwin-x64/isolate_snapshot.bin')
      .createSync(recursive: true);
    final File inputFramework = fileSystem.file(fileSystem.path.join(environment.buildDir.path, 'App.framework', 'App'))
      ..createSync(recursive: true)
      ..writeAsStringSync('ABC');

    await const ProfileMacOSBundleFlutterAssets().build(environment..defines[kBuildMode] = 'profile');
    final File outputFramework = fileSystem.file(fileSystem.path.join(environment.outputDir.path, 'App.framework', 'App'));

    expect(outputFramework.readAsStringSync(), 'ABC');

    inputFramework.writeAsStringSync('DEF');
    await const ProfileMacOSBundleFlutterAssets().build(environment..defines[kBuildMode] = 'profile');

    expect(outputFramework.readAsStringSync(), 'DEF');
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('DebugMacOSFramework creates expected binary with arm64 only arch', () async {
    environment.defines[kDarwinArchs] = 'arm64';
    processManager.addCommand(
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
        environment.buildDir.childFile('debug_app.cc').path,
        '-arch',
        'arm64',
        '-dynamiclib',
        '-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks',
        '-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks',
        '-install_name', '@rpath/App.framework/App',
        '-o',
        environment.buildDir
            .childDirectory('App.framework')
            .childFile('App')
            .path,
      ]),
    );

    await const DebugMacOSFramework().build(environment);
    expect(processManager.hasRemainingExpectations, isFalse);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('DebugMacOSFramework creates universal binary', () async {
    environment.defines[kDarwinArchs] = 'arm64 x86_64';
    processManager.addCommand(
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
        environment.buildDir.childFile('debug_app.cc').path,
        '-arch',
        'arm64',
        '-arch',
        'x86_64',
        '-dynamiclib',
        '-Xlinker', '-rpath', '-Xlinker', '@executable_path/Frameworks',
        '-Xlinker', '-rpath', '-Xlinker', '@loader_path/Frameworks',
        '-install_name', '@rpath/App.framework/App',
        '-o',
        environment.buildDir
            .childDirectory('App.framework')
            .childFile('App')
            .path,
      ]),
    );

    await const DebugMacOSFramework().build(environment);
    expect(processManager.hasRemainingExpectations, isFalse);
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });

  testUsingContext('CompileMacOSFramework creates universal binary', () async {
    environment.defines[kDarwinArchs] = 'arm64 x86_64';
    environment.defines[kBuildMode] = 'release';

    processManager.addCommands(<FakeCommand>[
      FakeCommand(command: <String>[
        'Artifact.genSnapshot.TargetPlatform.darwin.release',
        '--deterministic',
        '--snapshot_kind=app-aot-assembly',
        '--assembly=${environment.buildDir.childFile('arm64/snapshot_assembly.S').path}',
        '--strip',
        environment.buildDir.childFile('app.dill').path
      ]),
      FakeCommand(command: <String>[
        'Artifact.genSnapshot.TargetPlatform.darwin.release',
        '--deterministic',
        '--snapshot_kind=app-aot-assembly',
        '--assembly=${environment.buildDir.childFile('x86_64/snapshot_assembly.S').path}',
        '--strip',
        environment.buildDir.childFile('app.dill').path
      ]),
      FakeCommand(command: <String>[
        'xcrun', 'cc',  '-arch', 'arm64',
        '-c', environment.buildDir.childFile('arm64/snapshot_assembly.S').path,
        '-o', environment.buildDir.childFile('arm64/snapshot_assembly.o').path
      ]),
      FakeCommand(command: <String>[
        'xcrun', 'cc',  '-arch', 'x86_64',
        '-c', environment.buildDir.childFile('x86_64/snapshot_assembly.S').path,
        '-o', environment.buildDir.childFile('x86_64/snapshot_assembly.o').path
      ]),
      FakeCommand(command: <String>[
        'xcrun', 'clang', '-arch', 'arm64', '-dynamiclib', '-Xlinker', '-rpath',
        '-Xlinker', '@executable_path/Frameworks', '-Xlinker', '-rpath',
        '-Xlinker', '@loader_path/Frameworks',
        '-install_name', '@rpath/App.framework/App',
        '-o', environment.buildDir.childFile('arm64/App.framework/App').path,
        environment.buildDir.childFile('arm64/snapshot_assembly.o').path
      ]),
      FakeCommand(command: <String>[
        'xcrun', 'clang', '-arch', 'x86_64', '-dynamiclib', '-Xlinker', '-rpath',
        '-Xlinker', '@executable_path/Frameworks', '-Xlinker', '-rpath',
        '-Xlinker', '@loader_path/Frameworks',
        '-install_name', '@rpath/App.framework/App',
        '-o', environment.buildDir.childFile('x86_64/App.framework/App').path,
        environment.buildDir.childFile('x86_64/snapshot_assembly.o').path
      ]),
      FakeCommand(command: <String>[
        'lipo',
        environment.buildDir.childFile('arm64/App.framework/App').path,
        environment.buildDir.childFile('x86_64/App.framework/App').path,
        '-create',
        '-output',
        environment.buildDir.childFile('App.framework/App').path,
      ]),
    ]);

    await const CompileMacOSFramework().build(environment);
    expect(processManager.hasRemainingExpectations, isFalse);

  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    ProcessManager: () => processManager,
  });
}
