// 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_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/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/dart.dart';
import 'package:flutter_tools/src/build_system/targets/ios.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart';

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

const List<String> _kSharedConfig = <String>[
  '-dynamiclib',
  '-fembed-bitcode-marker',
  '-Xlinker',
  '-rpath',
  '-Xlinker',
  '@executable_path/Frameworks',
  '-Xlinker',
  '-rpath',
  '-Xlinker',
  '@loader_path/Frameworks',
  '-install_name',
  '@rpath/App.framework/App',
  '-isysroot',
];

void main() {
  Testbed testbed;
  Environment environment;
  ProcessManager processManager;

  setUp(() {
    testbed = Testbed(setup: () {
      environment = Environment.test(
        globals.fs.currentDirectory,
        defines: <String, String>{
          kTargetPlatform: 'ios',
        },
        processManager: processManager,
        artifacts: MockArtifacts(),
        logger: globals.logger,
        fileSystem: globals.fs,
      );
    });
  });

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

  test('DebugUniveralFramework creates expected binary with arm64 only arch', () => testbed.run(() async {
    environment.defines[kIosArchs] = 'arm64';
    processManager = FakeProcessManager.list(<FakeCommand>[
      // Create iphone stub.
      const FakeCommand(command: <String>['xcrun', '--sdk', 'iphoneos', '--show-sdk-path']),
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
         // iphone only gets 64 bit arch based on kIosArchs
        '-arch',
        'arm64',
        globals.fs.path.absolute(globals.fs.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
        ..._kSharedConfig,
        '',
        '-o',
        environment.buildDir.childFile('iphone_framework').path
      ]),
      // Create simulator stub.
      const FakeCommand(command: <String>['xcrun', '--sdk', 'iphonesimulator', '--show-sdk-path']),
      FakeCommand(command: <String>[
        'xcrun',
        'clang',
        '-x',
        'c',
        // Simulator only as x86_64 arch
        '-arch',
        'x86_64',
        globals.fs.path.absolute(globals.fs.path.join('.tmp_rand0', 'flutter_tools_stub_source.rand0', 'debug_app.cc')),
        ..._kSharedConfig,
        '',
        '-o',
        environment.buildDir.childFile('simulator_framework').path
      ]),
      // Lipo stubs together.
      FakeCommand(command: <String>[
        'xcrun',
        'lipo',
        '-create',
        environment.buildDir.childFile('iphone_framework').path,
        environment.buildDir.childFile('simulator_framework').path,
        '-output',
        environment.buildDir.childDirectory('App.framework').childFile('App').path,
      ]),
    ]);

    await const DebugUniveralFramework().build(environment);
  }, overrides: <Type, Generator>{
    ProcessManager: () => processManager,
  }));

  test('DebugIosApplicationBundle', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'debug';
    // Precompiled dart data
    when(globals.artifacts.getArtifactPath(Artifact.vmSnapshotData, mode: BuildMode.debug))
      .thenReturn('vm_snapshot_data');
    when(globals.artifacts.getArtifactPath(Artifact.isolateSnapshotData, mode: BuildMode.debug))
      .thenReturn('isolate_snapshot_data');
    globals.fs.file('vm_snapshot_data').createSync();
    globals.fs.file('isolate_snapshot_data').createSync();
    // Project info
    globals.fs.file('pubspec.yaml').writeAsStringSync('name: hello');
    globals.fs.file('.packages').writeAsStringSync('\n');
    // Plist file
    globals.fs.file(globals.fs.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);

    await const DebugIosApplicationBundle().build(environment);

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    expect(frameworkDirectory.childFile('App'), 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>{
    Artifacts: () => MockArtifacts(),
  }));

  test('ReleaseIosApplicationBundle', () => testbed.run(() async {
    environment.defines[kBuildMode] = 'release';

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

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

    await const ReleaseIosApplicationBundle().build(environment);

    final Directory frameworkDirectory = environment.outputDir.childDirectory('App.framework');
    expect(frameworkDirectory.childFile('App'), exists);
    expect(frameworkDirectory.childFile('Info.plist'), 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));
  }));
}

class MockArtifacts extends Mock implements Artifacts {}
