// Copyright 2015 The Chromium 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:async';
import 'dart:convert';

import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';

import '../artifacts.dart';
import '../base/common.dart';
import '../base/context.dart';
import '../base/file_system.dart';
import '../base/flags.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
import '../base/process.dart';
import '../base/process_manager.dart';
import '../base/utils.dart';
import '../cache.dart';
import '../dart/package_map.dart';
import '../device.dart';
import '../globals.dart';
import '../tester/flutter_tester.dart';
import '../usage.dart';
import '../version.dart';
import '../vmservice.dart';

const String kFlutterRootEnvironmentVariableName = 'FLUTTER_ROOT'; // should point to //flutter/ (root of flutter/flutter repo)
const String kFlutterEngineEnvironmentVariableName = 'FLUTTER_ENGINE'; // should point to //engine/src/ (root of flutter/engine repo)
const String kSnapshotFileName = 'flutter_tools.snapshot'; // in //flutter/bin/cache/
const String kFlutterToolsScriptFileName = 'flutter_tools.dart'; // in //flutter/packages/flutter_tools/bin/
const String kFlutterEnginePackageName = 'sky_engine';

class FlutterCommandRunner extends CommandRunner<Null> {
  FlutterCommandRunner({ bool verboseHelp: false }) : super(
    'flutter',
    'Manage your Flutter app development.\n'
      '\n'
      'Common commands:\n'
      '\n'
      '  flutter create <output directory>\n'
      '    Create a new Flutter project in the specified directory.\n'
      '\n'
      '  flutter run [options]\n'
      '    Run your Flutter application on an attached device or in an emulator.',
  ) {
    argParser.addFlag('verbose',
        abbr: 'v',
        negatable: false,
        help: 'Noisy logging, including all shell commands executed.');
    argParser.addFlag('quiet',
        negatable: false,
        hide: !verboseHelp,
        help: 'Reduce the amount of output from some commands.');
    argParser.addOption('device-id',
        abbr: 'd',
        help: 'Target device id or name (prefixes allowed).');
    argParser.addFlag('version',
        negatable: false,
        help: 'Reports the version of this tool.');
    argParser.addFlag('machine',
        negatable: false,
        hide: true);
    argParser.addFlag('color',
        negatable: true,
        hide: !verboseHelp,
        help: 'Whether to use terminal colors.');
    argParser.addFlag('suppress-analytics',
        negatable: false,
        hide: !verboseHelp,
        help: 'Suppress analytics reporting when this command runs.');
    argParser.addFlag('bug-report',
        negatable: false,
        help:
            'Captures a bug report file to submit to the Flutter team '
            '(contains local paths, device\nidentifiers, and log snippets).');
    argParser.addFlag('show-test-device',
        negatable: false,
        hide: !verboseHelp,
        help: 'List the special \'flutter-tester\' device in device listings. '
              'This headless device is used to\ntest Flutter tooling.');

    String packagesHelp;
    if (fs.isFileSync(kPackagesFileName))
      packagesHelp = '\n(defaults to "$kPackagesFileName")';
    else
      packagesHelp = '\n(required, since the current directory does not contain a "$kPackagesFileName" file)';
    argParser.addOption('packages',
        hide: !verboseHelp,
        help: 'Path to your ".packages" file.$packagesHelp');
    argParser.addOption('flutter-root',
        help: 'The root directory of the Flutter repository (uses \$$kFlutterRootEnvironmentVariableName if set).');

    if (verboseHelp)
      argParser.addSeparator('Local build selection options (not normally required):');

    argParser.addOption('local-engine-src-path',
        hide: !verboseHelp,
        help:
            'Path to your engine src directory, if you are building Flutter locally.\n'
            'Defaults to \$$kFlutterEngineEnvironmentVariableName if set, otherwise defaults to the path given in your pubspec.yaml\n'
            'dependency_overrides for $kFlutterEnginePackageName, if any, or, failing that, tries to guess at the location\n'
            'based on the value of the --flutter-root option.');

    argParser.addOption('local-engine',
        hide: !verboseHelp,
        help:
            'Name of a build output within the engine out directory, if you are building Flutter locally.\n'
            'Use this to select a specific version of the engine if you have built multiple engine targets.\n'
            'This path is relative to --local-engine-src-path/out.');
    argParser.addOption('record-to',
        hide: true,
        help:
            'Enables recording of process invocations (including stdout and stderr of all such invocations),\n'
            'and file system access (reads and writes).\n'
            'Serializes that recording to a directory with the path specified in this flag. If the\n'
            'directory does not already exist, it will be created.');
    argParser.addOption('replay-from',
        hide: true,
        help:
            'Enables mocking of process invocations by replaying their stdout, stderr, and exit code from\n'
            'the specified recording (obtained via --record-to). The path specified in this flag must refer\n'
            'to a directory that holds serialized process invocations structured according to the output of\n'
            '--record-to.');
  }

  @override
  ArgParser get argParser => _argParser;
  final ArgParser _argParser = new ArgParser(allowTrailingOptions: false);

  @override
  String get usageFooter {
    return 'Run "flutter help -v" for verbose help output, including less commonly used options.';
  }

  static String get _defaultFlutterRoot {
    if (platform.environment.containsKey(kFlutterRootEnvironmentVariableName))
      return platform.environment[kFlutterRootEnvironmentVariableName];
    try {
      if (platform.script.scheme == 'data')
        return '../..'; // we're running as a test
      final String script = platform.script.toFilePath();
      if (fs.path.basename(script) == kSnapshotFileName)
        return fs.path.dirname(fs.path.dirname(fs.path.dirname(script)));
      if (fs.path.basename(script) == kFlutterToolsScriptFileName)
        return fs.path.dirname(fs.path.dirname(fs.path.dirname(fs.path.dirname(script))));

      // If run from a bare script within the repo.
      if (script.contains('flutter/packages/'))
        return script.substring(0, script.indexOf('flutter/packages/') + 8);
      if (script.contains('flutter/examples/'))
        return script.substring(0, script.indexOf('flutter/examples/') + 8);
    } catch (error) {
      // we don't have a logger at the time this is run
      // (which is why we don't use printTrace here)
      print('Unable to locate flutter root: $error');
    }
    return '.';
  }

  @override
  Future<Null> run(Iterable<String> args) {
    // Have an invocation of 'build' print out it's sub-commands.
    // TODO(ianh): Move this to the Build command itself somehow.
    if (args.length == 1 && args.first == 'build')
      args = <String>['build', '-h'];

    return super.run(args);
  }

  @override
  Future<Null> runCommand(ArgResults topLevelResults) async {
    final Map<Type, dynamic> contextOverrides = <Type, dynamic>{
      Flags: new Flags(topLevelResults),
    };

    // Check for verbose.
    if (topLevelResults['verbose']) {
      // Override the logger.
      contextOverrides[Logger] = new VerboseLogger(logger);
    }

    if (topLevelResults['show-test-device'] ||
        topLevelResults['device-id'] == FlutterTesterDevices.kTesterDeviceId) {
      FlutterTesterDevices.showFlutterTesterDevice = true;
    }

    String recordTo = topLevelResults['record-to'];
    String replayFrom = topLevelResults['replay-from'];

    if (topLevelResults['bug-report']) {
      // --bug-report implies --record-to=<tmp_path>
      final Directory tmp = await const LocalFileSystem()
          .systemTempDirectory
          .createTemp('flutter_tools_');
      recordTo = tmp.path;

      // Record the arguments that were used to invoke this runner.
      final File manifest = tmp.childFile('MANIFEST.txt');
      final StringBuffer buffer = new StringBuffer()
        ..writeln('# arguments')
        ..writeln(topLevelResults.arguments)
        ..writeln()
        ..writeln('# rest')
        ..writeln(topLevelResults.rest);
      await manifest.writeAsString(buffer.toString(), flush: true);

      // ZIP the recording up once the recording has been serialized.
      addShutdownHook(() async {
        final File zipFile = getUniqueFile(fs.currentDirectory, 'bugreport', 'zip');
        os.zip(tmp, zipFile);
        printStatus(
            'Bug report written to ${zipFile.basename}.\n'
            'Note that this bug report contains local paths, device '
            'identifiers, and log snippets.');
      }, ShutdownStage.POST_PROCESS_RECORDING);
      addShutdownHook(() => tmp.delete(recursive: true), ShutdownStage.CLEANUP);
    }

    assert(recordTo == null || replayFrom == null);

    if (recordTo != null) {
      recordTo = recordTo.trim();
      if (recordTo.isEmpty)
        throwToolExit('record-to location not specified');
      contextOverrides.addAll(<Type, dynamic>{
        ProcessManager: getRecordingProcessManager(recordTo),
        FileSystem: getRecordingFileSystem(recordTo),
        Platform: await getRecordingPlatform(recordTo),
      });
      VMService.enableRecordingConnection(recordTo);
    }

    if (replayFrom != null) {
      replayFrom = replayFrom.trim();
      if (replayFrom.isEmpty)
        throwToolExit('replay-from location not specified');
      contextOverrides.addAll(<Type, dynamic>{
        ProcessManager: await getReplayProcessManager(replayFrom),
        FileSystem: getReplayFileSystem(replayFrom),
        Platform: await getReplayPlatform(replayFrom),
      });
      VMService.enableReplayConnection(replayFrom);
    }

    // We must set Cache.flutterRoot early because other features use it (e.g.
    // enginePath's initializer uses it).
    final String flutterRoot = topLevelResults['flutter-root'] ?? _defaultFlutterRoot;
    Cache.flutterRoot = fs.path.normalize(fs.path.absolute(flutterRoot));

    // Set up the tooling configuration.
    final String enginePath = _findEnginePath(topLevelResults);
    if (enginePath != null) {
      contextOverrides.addAll(<Type, dynamic>{
        Artifacts: Artifacts.getLocalEngine(enginePath, _findEngineBuildPath(topLevelResults, enginePath)),
      });
    }

    await context.run<Null>(
      overrides: contextOverrides.map<Type, Generator>((Type type, dynamic value) {
        return new MapEntry<Type, Generator>(type, () => value);
      }),
      body: () async {
        logger.quiet = topLevelResults['quiet'];

        if (topLevelResults.wasParsed('color'))
          logger.supportsColor = topLevelResults['color'];

        if (platform.environment['FLUTTER_ALREADY_LOCKED'] != 'true')
          await Cache.lock();

        if (topLevelResults['suppress-analytics'])
          flutterUsage.suppressAnalytics = true;

        _checkFlutterCopy();
        await FlutterVersion.instance.ensureVersionFile();
        if (topLevelResults.command?.name != 'upgrade') {
          await FlutterVersion.instance.checkFlutterVersionFreshness();
        }

        if (topLevelResults.wasParsed('packages'))
          PackageMap.globalPackagesPath = fs.path.normalize(fs.path.absolute(topLevelResults['packages']));

        // See if the user specified a specific device.
        deviceManager.specifiedDeviceId = topLevelResults['device-id'];

        if (topLevelResults['version']) {
          flutterUsage.sendCommand('version');
          String status;
          if (topLevelResults['machine']) {
            status = const JsonEncoder.withIndent('  ').convert(FlutterVersion.instance.toJson());
          } else {
            status = FlutterVersion.instance.toString();
          }
          printStatus(status);
          return;
        }

        if (topLevelResults['machine']) {
          throwToolExit('The --machine flag is only valid with the --version flag.', exitCode: 2);
        }

        await super.runCommand(topLevelResults);
      },
    );
  }

  String _tryEnginePath(String enginePath) {
    if (fs.isDirectorySync(fs.path.join(enginePath, 'out')))
      return enginePath;
    return null;
  }

  String _findEnginePath(ArgResults globalResults) {
    String engineSourcePath = globalResults['local-engine-src-path'] ?? platform.environment[kFlutterEngineEnvironmentVariableName];

    if (engineSourcePath == null && globalResults['local-engine'] != null) {
      try {
        final Uri engineUri = new PackageMap(PackageMap.globalPackagesPath).map[kFlutterEnginePackageName];
        if (engineUri != null) {
          engineSourcePath = fs.path.dirname(fs.path.dirname(fs.path.dirname(fs.path.dirname(engineUri.path))));
          final bool dirExists = fs.isDirectorySync(fs.path.join(engineSourcePath, 'out'));
          if (engineSourcePath == '/' || engineSourcePath.isEmpty || !dirExists)
            engineSourcePath = null;
        }
      } on FileSystemException {
        engineSourcePath = null;
      } on FormatException {
        engineSourcePath = null;
      }

      engineSourcePath ??= _tryEnginePath(fs.path.join(Cache.flutterRoot, '../engine/src'));

      if (engineSourcePath == null) {
        throwToolExit('Unable to detect local Flutter engine build directory.\n'
          'Either specify a dependency_override for the $kFlutterEnginePackageName package in your pubspec.yaml and\n'
          'ensure --package-root is set if necessary, or set the \$$kFlutterEngineEnvironmentVariableName environment variable, or\n'
          'use --local-engine-src-path to specify the path to the root of your flutter/engine repository.',
          exitCode: 2);
      }
    }

    if (engineSourcePath != null && _tryEnginePath(engineSourcePath) == null) {
      throwToolExit('Unable to detect a Flutter engine build directory in $engineSourcePath.\n'
        'Please ensure that $engineSourcePath is a Flutter engine \'src\' directory and that\n'
        'you have compiled the engine in that directory, which should produce an \'out\' directory',
        exitCode: 2);
    }

    return engineSourcePath;
  }

  EngineBuildPaths _findEngineBuildPath(ArgResults globalResults, String enginePath) {
    String localEngine;
    if (globalResults['local-engine'] != null) {
      localEngine = globalResults['local-engine'];
    } else {
      throwToolExit('You must specify --local-engine if you are using a locally built engine.', exitCode: 2);
    }

    final String engineBuildPath = fs.path.normalize(fs.path.join(enginePath, 'out', localEngine));
    if (!fs.isDirectorySync(engineBuildPath)) {
      throwToolExit('No Flutter engine build found at $engineBuildPath.', exitCode: 2);
    }

    // Determine the host engine directory associated with the local engine:
    // * strip '_sim_' since there are no host simulator builds.
    // * replace the target platform with host.
    final String basename = fs.path.basename(engineBuildPath);
    final String hostBasename = 'host_' + basename.replaceFirst('_sim_', '_').substring(basename.indexOf('_') + 1);
    final String engineHostBuildPath = fs.path.normalize(fs.path.join(fs.path.dirname(engineBuildPath), hostBasename));

    return new EngineBuildPaths(targetEngine: engineBuildPath, hostEngine: engineHostBuildPath);
  }

  static void initFlutterRoot() {
    Cache.flutterRoot ??= _defaultFlutterRoot;
  }

  /// Get all pub packages in the Flutter repo.
  List<Directory> getRepoPackages() {
    final String root = fs.path.absolute(Cache.flutterRoot);
    // not bin, and not the root
    return <String>['dev', 'examples', 'packages']
      .expand<String>((String path) => _gatherProjectPaths(fs.path.join(root, path)))
      .map((String dir) => fs.directory(dir))
      .toList();
  }

  static List<String> _gatherProjectPaths(String rootPath) {
    if (fs.isFileSync(fs.path.join(rootPath, '.dartignore')))
      return <String>[];


    final List<String> projectPaths = fs.directory(rootPath)
      .listSync(followLinks: false)
      .expand((FileSystemEntity entity) {
        return entity is Directory ? _gatherProjectPaths(entity.path) : <String>[];
      })
      .toList();

    if (fs.isFileSync(fs.path.join(rootPath, 'pubspec.yaml')))
      projectPaths.add(rootPath);

    return projectPaths;
  }

  void _checkFlutterCopy() {
    // If the current directory is contained by a flutter repo, check that it's
    // the same flutter that is currently running.
    String directory = fs.path.normalize(fs.path.absolute(fs.currentDirectory.path));

    // Check if the cwd is a flutter dir.
    while (directory.isNotEmpty) {
      if (_isDirectoryFlutterRepo(directory)) {
        if (!_compareResolvedPaths(directory, Cache.flutterRoot)) {
          printError(
            'Warning: the \'flutter\' tool you are currently running is not the one from the current directory:\n'
            '  running Flutter  : ${Cache.flutterRoot}\n'
            '  current directory: $directory\n'
            'This can happen when you have multiple copies of flutter installed. Please check your system path to verify\n'
            'that you\'re running the expected version (run \'flutter --version\' to see which flutter is on your path).\n'
          );
        }

        break;
      }

      final String parent = fs.path.dirname(directory);
      if (parent == directory)
        break;
      directory = parent;
    }

    // Check that the flutter running is that same as the one referenced in the pubspec.
    if (fs.isFileSync(kPackagesFileName)) {
      final PackageMap packageMap = new PackageMap(kPackagesFileName);
      final Uri flutterUri = packageMap.map['flutter'];

      if (flutterUri != null && (flutterUri.scheme == 'file' || flutterUri.scheme == '')) {
        // .../flutter/packages/flutter/lib
        final Uri rootUri = flutterUri.resolve('../../..');
        final String flutterPath = fs.path.normalize(fs.file(rootUri).absolute.path);

        if (!fs.isDirectorySync(flutterPath)) {
          printError(
            'Warning! This package referenced a Flutter repository via the .packages file that is\n'
            'no longer available. The repository from which the \'flutter\' tool is currently\n'
            'executing will be used instead.\n'
            '  running Flutter tool: ${Cache.flutterRoot}\n'
            '  previous reference  : $flutterPath\n'
            'This can happen if you deleted or moved your copy of the Flutter repository, or\n'
            'if it was on a volume that is no longer mounted or has been mounted at a\n'
            'different location. Please check your system path to verify that you are running\n'
            'the expected version (run \'flutter --version\' to see which flutter is on your path).\n'
          );
        } else if (!_compareResolvedPaths(flutterPath, Cache.flutterRoot)) {
          printError(
            'Warning! The \'flutter\' tool you are currently running is from a different Flutter\n'
            'repository than the one last used by this package. The repository from which the\n'
            '\'flutter\' tool is currently executing will be used instead.\n'
            '  running Flutter tool: ${Cache.flutterRoot}\n'
            '  previous reference  : $flutterPath\n'
            'This can happen when you have multiple copies of flutter installed. Please check\n'
            'your system path to verify that you are running the expected version (run\n'
            '\'flutter --version\' to see which flutter is on your path).\n'
          );
        }
      }
    }
  }

  // Check if `bin/flutter` and `bin/cache/engine.stamp` exist.
  bool _isDirectoryFlutterRepo(String directory) {
    return
      fs.isFileSync(fs.path.join(directory, 'bin/flutter')) &&
      fs.isFileSync(fs.path.join(directory, 'bin/cache/engine.stamp'));
  }
}

bool _compareResolvedPaths(String path1, String path2) {
  path1 = fs.directory(fs.path.absolute(path1)).resolveSymbolicLinksSync();
  path2 = fs.directory(fs.path.absolute(path2)).resolveSymbolicLinksSync();

  return path1 == path2;
}
