// 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:args/args.dart';

import 'package:flutter_tools/runner.dart' as runner;
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/common.dart';
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/attach.dart';
import 'package:flutter_tools/src/commands/doctor.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_device.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_sdk.dart';
import 'package:flutter_tools/src/fuchsia/fuchsia_workflow.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';

final ArgParser parser = ArgParser()
  ..addOption('build-dir', help: 'The fuchsia build directory')
  ..addOption('dart-sdk', help: 'The prebuilt dart SDK')
  ..addOption('target', help: 'The GN target to attach to')
  ..addOption('entrypoint', defaultsTo: 'main.dart', help: 'The filename of the main method. Defaults to main.dart')
  ..addOption('device', help: 'The device id to attach to')
  ..addOption('dev-finder', help: 'The location of the device-finder binary')
  ..addFlag('verbose', negatable: true);

// Track the original working directory so that the tool can find the
// flutter repo in third_party.
String originalWorkingDirectory;

Future<void> main(List<String> args) async {
  final ArgResults argResults = parser.parse(args);
  final bool verbose = argResults['verbose'] as bool;
  final String target = argResults['target'] as String;
  final List<String> targetParts = _extractPathAndName(target);
  final String path = targetParts[0];
  final String name = targetParts[1];
  final File dartSdk = globals.fs.file(argResults['dart-sdk']);
  final String buildDirectory = argResults['build-dir'] as String;
  final File frontendServer = globals.fs.file('$buildDirectory/host_x64/gen/third_party/flutter/frontend_server/frontend_server_tool.snapshot');
  final File sshConfig = globals.fs.file('$buildDirectory/ssh-keys/ssh_config');
  final File devFinder = globals.fs.file(argResults['dev-finder']);
  final File platformKernelDill = globals.fs.file('$buildDirectory/flutter_runner_patched_sdk/platform_strong.dill');
  final File flutterPatchedSdk = globals.fs.file('$buildDirectory/flutter_runner_patched_sdk');
  final String packages = '$buildDirectory/dartlang/gen/$path/${name}_dart_library.packages';
  final String outputDill = '$buildDirectory/${name}_tmp.dill';

  // TODO(jonahwilliams): running from fuchsia root hangs hot reload for some reason.
  // switch to the project root directory and run from there.
  originalWorkingDirectory = globals.fs.currentDirectory.path;
  globals.fs.currentDirectory = path;

  if (!devFinder.existsSync()) {
    print('Error: device-finder not found at ${devFinder.path}.');
    return 1;
  }
  if (!frontendServer.existsSync()) {
    print(
      'Error: frontend_server not found at ${frontendServer.path}. This '
      'Usually means you ran fx set without specifying '
      '--args=flutter_profile=true.'
    );
    return 1;
  }

  // Check for a package with a lib directory.
  final String entrypoint = argResults['entrypoint'] as String;
  String targetFile = 'lib/$entrypoint';
  if (!globals.fs.file(targetFile).existsSync()) {
    // Otherwise assume the package is flat.
    targetFile = entrypoint;
  }
  final String deviceName = argResults['device'] as String;
  final List<String> command = <String>[
    'attach',
    '--module',
    name,
    '--target',
    targetFile,
    '--target-model',
    'flutter', // TODO(jonahwilliams): change to flutter_runner when dart SDK rolls
    '--output-dill',
    outputDill,
    '--packages',
    packages,
    if (deviceName != null && deviceName.isNotEmpty) ...<String>['-d', deviceName],
    if (verbose) '--verbose',
  ];
  Cache.disableLocking(); // ignore: invalid_use_of_visible_for_testing_member
  await runner.run(
    command,
    () => <FlutterCommand>[
      _FuchsiaAttachCommand(),
      _FuchsiaDoctorCommand(), // If attach fails the tool will attempt to run doctor.
    ],
    verbose: verbose,
    muteCommandLogging: false,
    verboseHelp: false,
    overrides: <Type, Generator>{
      FeatureFlags: () => const _FuchsiaFeatureFlags(),
      DeviceManager: () => _FuchsiaDeviceManager(),
      FuchsiaArtifacts: () => FuchsiaArtifacts(sshConfig: sshConfig, devFinder: devFinder),
      Artifacts: () => OverrideArtifacts(
        parent: CachedArtifacts(
          fileSystem: globals.fs,
          cache: globals.cache,
          platform: globals.platform,
          operatingSystemUtils: globals.os,
        ),
        frontendServer: frontendServer,
        engineDartBinary: dartSdk,
        platformKernelDill: platformKernelDill,
        flutterPatchedSdk: flutterPatchedSdk,
      ),
    },
  );
}

// An implementation of [DeviceManager] that only supports fuchsia devices.
class _FuchsiaDeviceManager extends DeviceManager {
  @override
  List<DeviceDiscovery> get deviceDiscoverers => List<DeviceDiscovery>.unmodifiable(<DeviceDiscovery>[
    FuchsiaDevices(
      logger: globals.logger,
      platform: globals.platform,
      fuchsiaWorkflow: fuchsiaWorkflow,
      fuchsiaSdk: fuchsiaSdk,
    ),
  ]);

  @override
  bool isDeviceSupportedForProject(Device device, FlutterProject flutterProject) {
    return true;
  }
}

List<String> _extractPathAndName(String gnTarget) {
  // Separate strings like //path/to/target:app into [path/to/target, app]
  final int lastColon = gnTarget.lastIndexOf(':');
  if (lastColon < 0) {
    throwToolExit('invalid path: $gnTarget');
  }
  final String name = gnTarget.substring(lastColon + 1);
  // Skip '//' and chop off after :
  if ((gnTarget.length < 3) || (gnTarget[0] != '/') || (gnTarget[1] != '/')) {
    throwToolExit('invalid path: $gnTarget');
  }
  final String path = gnTarget.substring(2, lastColon);
  return <String>[path, name];
}

class _FuchsiaDoctorCommand extends DoctorCommand {
  @override
  Future<FlutterCommandResult> runCommand() async {
    Cache.flutterRoot = '$originalWorkingDirectory/third_party/dart-pkg/git/flutter';
    return super.runCommand();
  }
}

class _FuchsiaAttachCommand extends AttachCommand {
  @override
  Future<FlutterCommandResult> runCommand() async {
    Cache.flutterRoot = '$originalWorkingDirectory/third_party/dart-pkg/git/flutter';
    return super.runCommand();
  }
}

class _FuchsiaFeatureFlags extends FeatureFlags {
  const _FuchsiaFeatureFlags();

  @override
  bool get isLinuxEnabled => false;

  @override
  bool get isMacOSEnabled => false;

  @override
  bool get isWebEnabled => false;

  @override
  bool get isWindowsEnabled => false;

  @override
  bool get isAndroidEnabled => false;

  @override
  bool get isIOSEnabled => false;

  @override
  bool get isFuchsiaEnabled => true;

  @override
  bool get isSingleWidgetReloadEnabled => false;
}
