// 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:meta/meta.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';

import 'base/file_system.dart';
import 'base/utils.dart';
import 'build_info.dart';
import 'cache.dart';
import 'dart/sdk.dart';
import 'globals.dart' as globals;

enum Artifact {
  /// The tool which compiles a dart kernel file into native code.
  genSnapshot,
  /// The flutter tester binary.
  flutterTester,
  flutterFramework,
  /// The framework directory of the macOS desktop.
  flutterMacOSFramework,
  vmSnapshotData,
  isolateSnapshotData,
  platformKernelDill,
  platformLibrariesJson,
  flutterPatchedSdkPath,
  frontendServerSnapshotForEngineDartSdk,
  /// The root directory of the dart SDK.
  engineDartSdkPath,
  /// The dart binary used to execute any of the required snapshots.
  engineDartBinary,
  /// The dart snapshot of the dart2js compiler.
  dart2jsSnapshot,
  /// The dart snapshot of the dartdev compiler.
  dartdevcSnapshot,
  /// The dart snpashot of the kernel worker compiler.
  kernelWorkerSnapshot,
  /// The root of the web implementation of the dart SDK.
  flutterWebSdk,
  flutterWebLibrariesJson,
  /// The summary dill for the dartdevc target.
  webPlatformKernelDill,
  iosDeploy,
  idevicesyslog,
  idevicescreenshot,
  ideviceinstaller,
  iproxy,
  /// The root of the Linux desktop sources.
  linuxDesktopPath,
  /// The root of the Windows desktop sources.
  windowsDesktopPath,
  /// The root of the sky_engine package
  skyEnginePath,
  /// The location of the macOS engine podspec file.
  flutterMacOSPodspec,

  // Fuchsia artifacts from the engine prebuilts.
  fuchsiaKernelCompiler,
  fuchsiaFlutterRunner,

  /// Tools related to subsetting or icon font files.
  fontSubset,
  constFinder,
}

String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMode mode ]) {
  final String exe = platform == TargetPlatform.windows_x64 ? '.exe' : '';
  switch (artifact) {
    case Artifact.genSnapshot:
      return 'gen_snapshot';
    case Artifact.flutterTester:
      return 'flutter_tester$exe';
    case Artifact.flutterFramework:
      return 'Flutter.framework';
    case Artifact.flutterMacOSFramework:
      return 'FlutterMacOS.framework';
    case Artifact.vmSnapshotData:
      return 'vm_isolate_snapshot.bin';
    case Artifact.isolateSnapshotData:
      return 'isolate_snapshot.bin';
    case Artifact.platformKernelDill:
      return 'platform_strong.dill';
    case Artifact.platformLibrariesJson:
      return 'libraries.json';
    case Artifact.flutterPatchedSdkPath:
      assert(false, 'No filename for sdk path, should not be invoked');
      return null;
    case Artifact.flutterWebSdk:
      assert(false, 'No filename for web sdk path, should not be invoked');
      return null;
    case Artifact.engineDartSdkPath:
      return 'dart-sdk';
    case Artifact.frontendServerSnapshotForEngineDartSdk:
      return 'frontend_server.dart.snapshot';
    case Artifact.engineDartBinary:
      return 'dart$exe';
    case Artifact.dart2jsSnapshot:
      return 'dart2js.dart.snapshot';
    case Artifact.dartdevcSnapshot:
      return 'dartdevc.dart.snapshot';
    case Artifact.kernelWorkerSnapshot:
      return 'kernel_worker.dart.snapshot';
    case Artifact.iosDeploy:
      return 'ios-deploy';
    case Artifact.idevicesyslog:
      return 'idevicesyslog';
    case Artifact.idevicescreenshot:
      return 'idevicescreenshot';
    case Artifact.ideviceinstaller:
      return 'ideviceinstaller';
    case Artifact.iproxy:
      return 'iproxy';
    case Artifact.linuxDesktopPath:
      return '';
    case Artifact.windowsDesktopPath:
      return '';
    case Artifact.skyEnginePath:
      return 'sky_engine';
    case Artifact.flutterMacOSPodspec:
      return 'FlutterMacOS.podspec';
    case Artifact.webPlatformKernelDill:
      return 'flutter_ddc_sdk.dill';
    case Artifact.fuchsiaKernelCompiler:
      return 'kernel_compiler.snapshot';
    case Artifact.fuchsiaFlutterRunner:
      final String jitOrAot = mode.isJit ? '_jit' : '_aot';
      final String productOrNo = mode.isRelease ? '_product' : '';
      return 'flutter$jitOrAot${productOrNo}_runner-0.far';
    case Artifact.fontSubset:
      return 'font-subset$exe';
    case Artifact.constFinder:
      return 'const_finder.dart.snapshot';
    case Artifact.flutterWebLibrariesJson:
      return 'libraries.json';
  }
  assert(false, 'Invalid artifact $artifact.');
  return null;
}

class EngineBuildPaths {
  const EngineBuildPaths({
    @required this.targetEngine,
    @required this.hostEngine,
  }) : assert(targetEngine != null),
       assert(hostEngine != null);

  final String targetEngine;
  final String hostEngine;
}

// Manages the engine artifacts of Flutter.
abstract class Artifacts {
  static LocalEngineArtifacts getLocalEngine(EngineBuildPaths engineBuildPaths) {
    return LocalEngineArtifacts(
      engineBuildPaths.targetEngine,
      engineBuildPaths.hostEngine,
      cache: globals.cache,
      fileSystem: globals.fs,
      processManager: globals.processManager,
      platform: globals.platform,
    );
  }

  // Returns the requested [artifact] for the [platform] and [mode] combination.
  String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode });

  // Returns which set of engine artifacts is currently used for the [platform]
  // and [mode] combination.
  String getEngineType(TargetPlatform platform, [ BuildMode mode ]);
}


/// Manages the engine artifacts downloaded to the local cache.
class CachedArtifacts extends Artifacts {
  CachedArtifacts({
    @required FileSystem fileSystem,
    @required Platform platform,
    @required Cache cache,
  }) : _fileSystem = fileSystem,
       _platform = platform,
       _cache = cache;

  final FileSystem _fileSystem;
  final Platform _platform;
  final Cache _cache;

  @override
  String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
    switch (platform) {
      case TargetPlatform.android_arm:
      case TargetPlatform.android_arm64:
      case TargetPlatform.android_x64:
      case TargetPlatform.android_x86:
        return _getAndroidArtifactPath(artifact, platform, mode);
      case TargetPlatform.ios:
        return _getIosArtifactPath(artifact, platform, mode);
      case TargetPlatform.darwin_x64:
        return _getDarwinArtifactPath(artifact, platform, mode);
      case TargetPlatform.fuchsia_arm64:
      case TargetPlatform.fuchsia_x64:
        return _getFuchsiaArtifactPath(artifact, platform, mode);
      case TargetPlatform.linux_x64:
      case TargetPlatform.windows_x64:
      case TargetPlatform.tester:
      case TargetPlatform.web_javascript:
      default: // could be null, but that can't be specified as a case.
        return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform(_platform), mode);
    }
  }

  @override
  String getEngineType(TargetPlatform platform, [ BuildMode mode ]) {
    return _fileSystem.path.basename(_getEngineArtifactsPath(platform, mode));
  }

  String _getDarwinArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
    // When platform is null, a generic host platform artifact is being requested
    // and not the gen_snapshot for darwin as a target platform.
    if (platform != null && artifact == Artifact.genSnapshot) {
      final String engineDir = _getEngineArtifactsPath(platform, mode);
      return _fileSystem.path.join(engineDir, _artifactToFileName(artifact));
    }
    return _getHostArtifactPath(artifact, platform ?? _currentHostPlatform(_platform), mode);
  }

  String _getAndroidArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
    final String engineDir = _getEngineArtifactsPath(platform, mode);
    switch (artifact) {
      case Artifact.frontendServerSnapshotForEngineDartSdk:
        assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
        return _fileSystem.path.join(engineDir, _artifactToFileName(artifact));
      case Artifact.genSnapshot:
        assert(mode != BuildMode.debug, 'Artifact $artifact only available in non-debug mode.');
        final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
        return _fileSystem.path.join(engineDir, hostPlatform, _artifactToFileName(artifact));
      default:
        return _getHostArtifactPath(artifact, platform, mode);
    }
  }

  String _getIosArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
    switch (artifact) {
      case Artifact.genSnapshot:
      case Artifact.flutterFramework:
      case Artifact.frontendServerSnapshotForEngineDartSdk:
        final String artifactFileName = _artifactToFileName(artifact);
        final String engineDir = _getEngineArtifactsPath(platform, mode);
        return _fileSystem.path.join(engineDir, artifactFileName);
      case Artifact.idevicescreenshot:
      case Artifact.idevicesyslog:
        final String artifactFileName = _artifactToFileName(artifact);
        return _cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
      case Artifact.iosDeploy:
        final String artifactFileName = _artifactToFileName(artifact);
        return _cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
      case Artifact.ideviceinstaller:
        final String artifactFileName = _artifactToFileName(artifact);
        return _cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
      case Artifact.iproxy:
        final String artifactFileName = _artifactToFileName(artifact);
        return _cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
      default:
        return _getHostArtifactPath(artifact, platform, mode);
    }
  }

  String _getFuchsiaArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
    final String root = _fileSystem.path.join(
      _cache.getArtifactDirectory('flutter_runner').path,
      'flutter',
      fuchsiaArchForTargetPlatform(platform),
      mode.isRelease ? 'release' : mode.toString(),
    );
    final String runtime = mode.isJit ? 'jit' : 'aot';
    switch (artifact) {
      case Artifact.genSnapshot:
        final String genSnapshot = mode.isRelease ? 'gen_snapshot_product' : 'gen_snapshot';
        return _fileSystem.path.join(root, runtime, 'dart_binaries', genSnapshot);
      case Artifact.flutterPatchedSdkPath:
        const String artifactFileName = 'flutter_runner_patched_sdk';
        return _fileSystem.path.join(root, runtime, artifactFileName);
      case Artifact.platformKernelDill:
        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
        return _fileSystem.path.join(root, runtime, 'flutter_runner_patched_sdk', artifactFileName);
      case Artifact.fuchsiaKernelCompiler:
        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
        return _fileSystem.path.join(root, runtime, 'dart_binaries', artifactFileName);
      case Artifact.fuchsiaFlutterRunner:
        final String artifactFileName = _artifactToFileName(artifact, platform, mode);
        return _fileSystem.path.join(root, runtime, artifactFileName);
      default:
        return _getHostArtifactPath(artifact, platform, mode);
    }
  }

  String _getFlutterPatchedSdkPath(BuildMode mode) {
    final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
    return _fileSystem.path.join(engineArtifactsPath, 'common',
        mode == BuildMode.release ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
  }

  String _getFlutterWebSdkPath() {
    return _cache.getWebSdkDirectory().path;
  }

  String _getHostArtifactPath(Artifact artifact, TargetPlatform platform, BuildMode mode) {
    assert(platform != null);
    switch (artifact) {
      case Artifact.genSnapshot:
        // For script snapshots any gen_snapshot binary will do. Returning gen_snapshot for
        // android_arm in profile mode because it is available on all supported host platforms.
        return _getAndroidArtifactPath(artifact, TargetPlatform.android_arm, BuildMode.profile);
      case Artifact.flutterTester:
      case Artifact.vmSnapshotData:
      case Artifact.isolateSnapshotData:
      case Artifact.frontendServerSnapshotForEngineDartSdk:
        final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
        final String platformDirName = getNameForTargetPlatform(platform);
        return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
      case Artifact.engineDartSdkPath:
        return dartSdkPath;
      case Artifact.engineDartBinary:
        return _fileSystem.path.join(dartSdkPath, 'bin', _artifactToFileName(artifact, platform));
      case Artifact.platformKernelDill:
        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), _artifactToFileName(artifact));
      case Artifact.platformLibrariesJson:
        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), 'lib', _artifactToFileName(artifact));
      case Artifact.flutterPatchedSdkPath:
        return _getFlutterPatchedSdkPath(mode);
      case Artifact.flutterWebSdk:
        return _getFlutterWebSdkPath();
      case Artifact.flutterWebLibrariesJson:
        return _fileSystem.path.join(_getFlutterWebSdkPath(), _artifactToFileName(artifact));
      case Artifact.webPlatformKernelDill:
        return _fileSystem.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
      case Artifact.dart2jsSnapshot:
        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
      case Artifact.dartdevcSnapshot:
        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
      case Artifact.kernelWorkerSnapshot:
        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', _artifactToFileName(artifact));
      case Artifact.flutterMacOSFramework:
      case Artifact.linuxDesktopPath:
      case Artifact.windowsDesktopPath:
      case Artifact.flutterMacOSPodspec:
        // TODO(jonahwilliams): remove once debug desktop artifacts are uploaded
        // under a separate directory from the host artifacts.
        // https://github.com/flutter/flutter/issues/38935
        String platformDirName = getNameForTargetPlatform(platform);
        if (mode == BuildMode.profile || mode == BuildMode.release) {
          platformDirName = '$platformDirName-${getNameForBuildMode(mode)}';
        }
        final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
        return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
      case Artifact.skyEnginePath:
        final Directory dartPackageDirectory = _cache.getCacheDir('pkg');
        return _fileSystem.path.join(dartPackageDirectory.path,  _artifactToFileName(artifact));
      case Artifact.fontSubset:
      case Artifact.constFinder:
        return _cache.getArtifactDirectory('engine')
                     .childDirectory(getNameForTargetPlatform(platform))
                     .childFile(_artifactToFileName(artifact, platform, mode))
                     .path;
      default:
        assert(false, 'Artifact $artifact not available for platform $platform.');
        return null;
    }
  }

  String _getEngineArtifactsPath(TargetPlatform platform, [ BuildMode mode ]) {
    final String engineDir = _cache.getArtifactDirectory('engine').path;
    final String platformName = getNameForTargetPlatform(platform);
    switch (platform) {
      case TargetPlatform.linux_x64:
      case TargetPlatform.darwin_x64:
      case TargetPlatform.windows_x64:
        // TODO(jonahwilliams): remove once debug desktop artifacts are uploaded
        // under a separate directory from the host artifacts.
        // https://github.com/flutter/flutter/issues/38935
        if (mode == BuildMode.debug || mode == null) {
          return _fileSystem.path.join(engineDir, platformName);
        }
        final String suffix = mode != BuildMode.debug ? '-${snakeCase(getModeName(mode), '-')}' : '';
        return _fileSystem.path.join(engineDir, platformName + suffix);
      case TargetPlatform.fuchsia_arm64:
      case TargetPlatform.fuchsia_x64:
      case TargetPlatform.tester:
      case TargetPlatform.web_javascript:
        assert(mode == null, 'Platform $platform does not support different build modes.');
        return _fileSystem.path.join(engineDir, platformName);
      case TargetPlatform.ios:
      case TargetPlatform.android_arm:
      case TargetPlatform.android_arm64:
      case TargetPlatform.android_x64:
      case TargetPlatform.android_x86:
        assert(mode != null, 'Need to specify a build mode for platform $platform.');
        final String suffix = mode != BuildMode.debug ? '-${snakeCase(getModeName(mode), '-')}' : '';
        return _fileSystem.path.join(engineDir, platformName + suffix);
      case TargetPlatform.android:
        assert(false, 'cannot use TargetPlatform.android to look up artifacts');
        return null;
    }
    assert(false, 'Invalid platform $platform.');
    return null;
  }
}

TargetPlatform _currentHostPlatform(Platform platform) {
  if (platform.isMacOS) {
    return TargetPlatform.darwin_x64;
  }
  if (platform.isLinux) {
    return TargetPlatform.linux_x64;
  }
  if (platform.isWindows) {
    return TargetPlatform.windows_x64;
  }
  throw UnimplementedError('Host OS not supported.');
}

HostPlatform _currentHostPlatformAsHost(Platform platform) {
  if (platform.isMacOS) {
    return HostPlatform.darwin_x64;
  }
  if (platform.isLinux) {
    return HostPlatform.linux_x64;
  }
  if (platform.isWindows) {
    return HostPlatform.windows_x64;
  }
  throw UnimplementedError('Host OS not supported.');
}

/// Manages the artifacts of a locally built engine.
class LocalEngineArtifacts extends Artifacts {
  LocalEngineArtifacts(
    this.engineOutPath,
    this._hostEngineOutPath, {
    @required FileSystem fileSystem,
    @required Cache cache,
    @required ProcessManager processManager,
    @required Platform platform,
  }) : _fileSystem = fileSystem,
       _cache = cache,
       _processManager = processManager,
       _platform = platform;

  final String engineOutPath; // TODO(goderbauer): This should be private.
  final String _hostEngineOutPath;
  final FileSystem _fileSystem;
  final Cache _cache;
  final ProcessManager _processManager;
  final Platform _platform;

  @override
  String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
    platform ??= _currentHostPlatform(_platform);
    final String artifactFileName = _artifactToFileName(artifact, platform, mode);
    switch (artifact) {
      case Artifact.genSnapshot:
        return _genSnapshotPath();
      case Artifact.flutterTester:
        return _flutterTesterPath(platform);
      case Artifact.isolateSnapshotData:
      case Artifact.vmSnapshotData:
        return _fileSystem.path.join(engineOutPath, 'gen', 'flutter', 'lib', 'snapshot', artifactFileName);
      case Artifact.platformKernelDill:
        if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
          return _fileSystem.path.join(engineOutPath, 'flutter_runner_patched_sdk', artifactFileName);
        }
        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), artifactFileName);
      case Artifact.platformLibrariesJson:
        return _fileSystem.path.join(_getFlutterPatchedSdkPath(mode), 'lib', artifactFileName);
      case Artifact.flutterFramework:
        return _fileSystem.path.join(engineOutPath, artifactFileName);
      case Artifact.flutterMacOSFramework:
        return _fileSystem.path.join(engineOutPath, artifactFileName);
      case Artifact.flutterPatchedSdkPath:
        // When using local engine always use [BuildMode.debug] regardless of
        // what was specified in [mode] argument because local engine will
        // have only one flutter_patched_sdk in standard location, that
        // is happen to be what debug(non-release) mode is using.
        if (platform == TargetPlatform.fuchsia_x64 || platform == TargetPlatform.fuchsia_arm64) {
          return _fileSystem.path.join(engineOutPath, 'flutter_runner_patched_sdk');
        }
        return _getFlutterPatchedSdkPath(BuildMode.debug);
      case Artifact.flutterWebSdk:
        return _getFlutterWebSdkPath();
      case Artifact.frontendServerSnapshotForEngineDartSdk:
        return _fileSystem.path.join(_hostEngineOutPath, 'gen', artifactFileName);
      case Artifact.engineDartSdkPath:
        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk');
      case Artifact.engineDartBinary:
        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', artifactFileName);
      case Artifact.dart2jsSnapshot:
        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
      case Artifact.dartdevcSnapshot:
        return _fileSystem.path.join(dartSdkPath, 'bin', 'snapshots', artifactFileName);
      case Artifact.kernelWorkerSnapshot:
        return _fileSystem.path.join(_hostEngineOutPath, 'dart-sdk', 'bin', 'snapshots', artifactFileName);
      case Artifact.idevicescreenshot:
      case Artifact.idevicesyslog:
        return _cache.getArtifactDirectory('libimobiledevice').childFile(artifactFileName).path;
      case Artifact.ideviceinstaller:
        return _cache.getArtifactDirectory('ideviceinstaller').childFile(artifactFileName).path;
      case Artifact.iosDeploy:
        return _cache.getArtifactDirectory('ios-deploy').childFile(artifactFileName).path;
      case Artifact.iproxy:
        return _cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
      case Artifact.linuxDesktopPath:
        return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
      case Artifact.windowsDesktopPath:
        return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
      case Artifact.skyEnginePath:
        return _fileSystem.path.join(_hostEngineOutPath, 'gen', 'dart-pkg', artifactFileName);
      case Artifact.flutterMacOSPodspec:
        return _fileSystem.path.join(_hostEngineOutPath, _artifactToFileName(artifact));
      case Artifact.webPlatformKernelDill:
        return _fileSystem.path.join(_getFlutterWebSdkPath(), 'kernel', _artifactToFileName(artifact));
      case Artifact.fuchsiaKernelCompiler:
        final String hostPlatform = getNameForHostPlatform(getCurrentHostPlatform());
        final String modeName = mode.isRelease ? 'release' : mode.toString();
        final String dartBinaries = 'dart_binaries-$modeName-$hostPlatform';
        return _fileSystem.path.join(engineOutPath, 'host_bundle', dartBinaries, 'kernel_compiler.dart.snapshot');
      case Artifact.fuchsiaFlutterRunner:
        final String jitOrAot = mode.isJit ? '_jit' : '_aot';
        final String productOrNo = mode.isRelease ? '_product' : '';
        return _fileSystem.path.join(engineOutPath, 'flutter$jitOrAot${productOrNo}_runner-0.far');
      case Artifact.fontSubset:
        return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
      case Artifact.constFinder:
        return _fileSystem.path.join(_hostEngineOutPath, 'gen', artifactFileName);
      case Artifact.flutterWebLibrariesJson:
        return _fileSystem.path.join(_getFlutterWebSdkPath(), artifactFileName);
    }
    assert(false, 'Invalid artifact $artifact.');
    return null;
  }

  @override
  String getEngineType(TargetPlatform platform, [ BuildMode mode ]) {
    return _fileSystem.path.basename(engineOutPath);
  }

  String _getFlutterPatchedSdkPath(BuildMode buildMode) {
    return _fileSystem.path.join(engineOutPath,
        buildMode == BuildMode.release ? 'flutter_patched_sdk_product' : 'flutter_patched_sdk');
  }

  String _getFlutterWebSdkPath() {
    return _fileSystem.path.join(engineOutPath, 'flutter_web_sdk');
  }

  String _genSnapshotPath() {
    const List<String> clangDirs = <String>['.', 'clang_x64', 'clang_x86', 'clang_i386'];
    final String genSnapshotName = _artifactToFileName(Artifact.genSnapshot);
    for (final String clangDir in clangDirs) {
      final String genSnapshotPath = _fileSystem.path.join(engineOutPath, clangDir, genSnapshotName);
      if (_processManager.canRun(genSnapshotPath)) {
        return genSnapshotPath;
      }
    }
    throw Exception('Unable to find $genSnapshotName');
  }

  String _flutterTesterPath(TargetPlatform platform) {
    final HostPlatform hostPlatform = _currentHostPlatformAsHost(_platform);
    if (hostPlatform == HostPlatform.linux_x64) {
      return _fileSystem.path.join(engineOutPath, _artifactToFileName(Artifact.flutterTester));
    } else if (hostPlatform == HostPlatform.darwin_x64) {
      return _fileSystem.path.join(engineOutPath, 'flutter_tester');
    } else if (hostPlatform == HostPlatform.windows_x64) {
      return _fileSystem.path.join(engineOutPath, 'flutter_tester.exe');
    }
    throw Exception('Unsupported platform $platform.');
  }
}

/// An implementation of [Artifacts] that provides individual overrides.
///
/// If an artifact is not provided, the lookup delegates to the parent.
class OverrideArtifacts implements Artifacts {
  /// Creates a new [OverrideArtifacts].
  ///
  /// [parent] must be provided.
  OverrideArtifacts({
    @required this.parent,
    this.frontendServer,
    this.engineDartBinary,
    this.platformKernelDill,
    this.flutterPatchedSdk,
  }) : assert(parent != null);

  final Artifacts parent;
  final File frontendServer;
  final File engineDartBinary;
  final File platformKernelDill;
  final File flutterPatchedSdk;

  @override
  String getArtifactPath(Artifact artifact, { TargetPlatform platform, BuildMode mode }) {
    if (artifact == Artifact.frontendServerSnapshotForEngineDartSdk && frontendServer != null) {
      return frontendServer.path;
    }
    if (artifact == Artifact.engineDartBinary && engineDartBinary != null) {
      return engineDartBinary.path;
    }
    if (artifact == Artifact.platformKernelDill && platformKernelDill != null) {
      return platformKernelDill.path;
    }
    if (artifact == Artifact.flutterPatchedSdkPath && flutterPatchedSdk != null) {
      return flutterPatchedSdk.path;
    }
    return parent.getArtifactPath(artifact, platform: platform, mode: mode);
  }

  @override
  String getEngineType(TargetPlatform platform, [ BuildMode mode ]) => parent.getEngineType(platform, mode);
}
