// Copyright 2013 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.6
import 'dart:async';
import 'dart:io' as io;

import 'package:archive/archive.dart';
import 'package:archive/archive_io.dart';
import 'package:args/args.dart';
import 'package:http/http.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart';

import 'common.dart';
import 'environment.dart';
import 'exceptions.dart';

class ChromeArgParser extends BrowserArgParser {
  static final ChromeArgParser _singletonInstance = ChromeArgParser._();

  /// The [ChromeArgParser] singleton.
  static ChromeArgParser get instance => _singletonInstance;

  String _version;
  int _pinnedChromeBuildNumber;

  ChromeArgParser._();

  @override
  void populateOptions(ArgParser argParser) {
    final YamlMap browserLock = BrowserLock.instance.configuration;
    _pinnedChromeBuildNumber =
        PlatformBinding.instance.getChromeBuild(browserLock);

    argParser
      ..addOption(
        'chrome-version',
        defaultsTo: '$pinnedChromeBuildNumber',
        help: 'The Chrome version to use while running tests. If the requested '
            'version has not been installed, it will be downloaded and installed '
            'automatically. A specific Chrome build version number, such as 695653, '
            'will use that version of Chrome. Value "latest" will use the latest '
            'available build of Chrome, installing it if necessary. Value "system" '
            'will use the manually installed version of Chrome on this computer.',
      );
  }

  @override
  void parseOptions(ArgResults argResults) {
    _version = argResults['chrome-version'] as String;
  }

  @override
  String get version => _version;

  String get pinnedChromeBuildNumber => _pinnedChromeBuildNumber.toString();
}

/// Returns the installation of Chrome, installing it if necessary.
///
/// If [requestedVersion] is null, uses the version specified on the
/// command-line. If not specified on the command-line, uses the version
/// specified in the "browser_lock.yaml" file.
///
/// If [requestedVersion] is not null, installs that version. The value
/// may be "latest" (the latest available build of Chrome), "system"
/// (manually installed Chrome on the current operating system), or an
/// exact build nuber, such as 695653. Build numbers can be found here:
///
/// https://commondatastorage.googleapis.com/chromium-browser-snapshots/index.html?prefix=Linux_x64/
Future<BrowserInstallation> getOrInstallChrome(
  String requestedVersion, {
  StringSink infoLog,
}) async {
  infoLog ??= io.stdout;

  if (requestedVersion == 'system') {
    return BrowserInstallation(
      version: 'system',
      executable: await _findSystemChromeExecutable(),
    );
  }

  ChromeInstaller installer;
  try {
    installer = requestedVersion == 'latest'
        ? await ChromeInstaller.latest()
        : ChromeInstaller(version: requestedVersion);

    if (installer.isInstalled) {
      infoLog.writeln(
          'Installation was skipped because Chrome version ${installer.version} is already installed.');
    } else {
      infoLog.writeln('Installing Chrome version: ${installer.version}');
      await installer.install();
      final BrowserInstallation installation = installer.getInstallation();
      infoLog.writeln(
          'Installations complete. To launch it run ${installation.executable}');
    }
    return installer.getInstallation();
  } finally {
    installer?.close();
  }
}

Future<String> _findSystemChromeExecutable() async {
  final io.ProcessResult which =
      await io.Process.run('which', <String>['google-chrome']);

  if (which.exitCode != 0) {
    throw BrowserInstallerException(
        'Failed to locate system Chrome installation.');
  }

  return which.stdout as String;
}

/// Manages the installation of a particular [version] of Chrome.
class ChromeInstaller {
  factory ChromeInstaller({
    @required String version,
  }) {
    if (version == 'system') {
      throw BrowserInstallerException(
          'Cannot install system version of Chrome. System Chrome must be installed manually.');
    }
    if (version == 'latest') {
      throw BrowserInstallerException(
          'Expected a concrete Chromer version, but got $version. Maybe use ChromeInstaller.latest()?');
    }
    final io.Directory chromeInstallationDir = io.Directory(
      path.join(environment.webUiDartToolDir.path, 'chrome'),
    );
    final io.Directory versionDir = io.Directory(
      path.join(chromeInstallationDir.path, version),
    );
    return ChromeInstaller._(
      version: version,
      chromeInstallationDir: chromeInstallationDir,
      versionDir: versionDir,
    );
  }

  static Future<ChromeInstaller> latest() async {
    final String latestVersion = await fetchLatestChromeVersion();
    return ChromeInstaller(version: latestVersion);
  }

  ChromeInstaller._({
    @required this.version,
    @required this.chromeInstallationDir,
    @required this.versionDir,
  });

  /// Chrome version managed by this installer.
  final String version;

  /// HTTP client used to download Chrome.
  final Client client = Client();

  /// Root directory that contains Chrome versions.
  final io.Directory chromeInstallationDir;

  /// Installation directory for Chrome of the requested [version].
  final io.Directory versionDir;

  bool get isInstalled {
    return versionDir.existsSync();
  }

  BrowserInstallation getInstallation() {
    if (!isInstalled) {
      return null;
    }

    return BrowserInstallation(
      version: version,
      executable: PlatformBinding.instance.getChromeExecutablePath(versionDir),
    );
  }

  Future<void> install() async {
    if (versionDir.existsSync() && !isLuci) {
      versionDir.deleteSync(recursive: true);
      versionDir.createSync(recursive: true);
    } else if (versionDir.existsSync() && isLuci) {
      print('INFO: Chrome version directory in LUCI: '
          '${versionDir.path}');
    } else if (!versionDir.existsSync() && isLuci) {
      // Chrome should have been deployed as a CIPD package on LUCI.
      // Throw if it does not exists.
      throw StateError('Failed to locate Chrome on LUCI on path:'
          '${versionDir.path}');
    } else {
      // If the directory does not exists and felt is not running on LUCI.
      versionDir.createSync(recursive: true);
    }

    print('INFO: Starting Chrome download.');

    final String url = PlatformBinding.instance.getChromeDownloadUrl(version);
    final StreamedResponse download = await client.send(Request(
      'GET',
      Uri.parse(url),
    ));

    final io.File downloadedFile =
        io.File(path.join(versionDir.path, 'chrome.zip'));
    await download.stream.pipe(downloadedFile.openWrite());

    /// Windows LUCI bots does not have a `unzip`. Instead we are
    /// using `archive` pub package.
    ///
    /// We didn't use `archieve` on Mac/Linux since the new files have
    /// permission issues. For now we are not able change file permissions
    /// from dart.
    /// See: https://github.com/dart-lang/sdk/issues/15078.
    if (io.Platform.isWindows) {
      final Stopwatch stopwatch = Stopwatch()..start();

      // Read the Zip file from disk.
      final bytes = downloadedFile.readAsBytesSync();

      final Archive archive = ZipDecoder().decodeBytes(bytes);

      // Extract the contents of the Zip archive to disk.
      for (final ArchiveFile file in archive) {
        final String filename = file.name;
        if (file.isFile) {
          final data = file.content as List<int>;
          io.File(path.join(versionDir.path, filename))
            ..createSync(recursive: true)
            ..writeAsBytesSync(data);
        } else {
          io.Directory(path.join(versionDir.path, filename))
            ..create(recursive: true);
        }
      }

      stopwatch.stop();
      print('INFO: The unzip took ${stopwatch.elapsedMilliseconds ~/ 1000} seconds.');
    } else {
      final io.ProcessResult unzipResult =
          await io.Process.run('unzip', <String>[
        downloadedFile.path,
        '-d',
        versionDir.path,
      ]);
      if (unzipResult.exitCode != 0) {
        throw BrowserInstallerException(
            'Failed to unzip the downloaded Chrome archive ${downloadedFile.path}.\n'
            'With the version path ${versionDir.path}\n'
            'The unzip process exited with code ${unzipResult.exitCode}.');
      }
    }

    downloadedFile.deleteSync();
  }

  void close() {
    client.close();
  }
}

/// Fetches the latest available Chrome build version.
Future<String> fetchLatestChromeVersion() async {
  final Client client = Client();
  try {
    final Response response = await client.get(
        Uri.parse('https://www.googleapis.com/download/storage/v1/b/chromium-browser-snapshots/o/Linux_x64%2FLAST_CHANGE?alt=media'));
    if (response.statusCode != 200) {
      throw BrowserInstallerException(
          'Failed to fetch latest Chrome version. Server returned status code ${response.statusCode}');
    }
    return response.body;
  } finally {
    client.close();
  }
}

/// Get the Chrome Driver version for the system Chrome.
// TODO(nurhan): https://github.com/flutter/flutter/issues/53179
Future<String> queryChromeDriverVersion() async {
  final int chromeVersion = await _querySystemChromeMajorVersion();
  final io.File lockFile = io.File(
      path.join(environment.webUiRootDir.path, 'dev', 'driver_version.yaml'));
  YamlMap _configuration = loadYaml(lockFile.readAsStringSync()) as YamlMap;
  final String chromeDriverVersion =
      _configuration['chrome'][chromeVersion] as String;
  return chromeDriverVersion;
}

/// Make sure LUCI bot has the pinned Chrome version and return the executable.
///
/// We are using CIPD packages in LUCI. The pinned chrome version from the
/// `browser_lock.yaml` file will already be installed in the LUCI bot.
/// Verify if Chrome is installed and use it for the integration tests.
String preinstalledChromeExecutable() {
  // Note that build number and major version is different for Chrome.
  // For example for a build number `753189`, major version is 83.
  final String buildNumber = ChromeArgParser.instance.pinnedChromeBuildNumber;
  final ChromeInstaller chromeInstaller = ChromeInstaller(version: buildNumber);
  if (chromeInstaller.isInstalled) {
    print('INFO: Found chrome executable for LUCI: '
        '${chromeInstaller.getInstallation().executable}');
    return chromeInstaller.getInstallation().executable;
  } else {
    throw StateError(
        'Failed to locate pinned Chrome build: $buildNumber on LUCI.');
  }
}

Future<int> _querySystemChromeMajorVersion() async {
  String chromeExecutable = '';
  // LUCI uses the Chrome from CIPD packages.
  if (isLuci) {
    chromeExecutable = preinstalledChromeExecutable();
  } else if (io.Platform.isLinux) {
    chromeExecutable = 'google-chrome';
  } else if (io.Platform.isMacOS) {
    chromeExecutable = await _findChromeExecutableOnMac();
  } else {
    throw UnimplementedError('Web installers only work on Linux and Mac.');
  }

  final io.ProcessResult versionResult =
      await io.Process.run('$chromeExecutable', <String>['--version']);

  if (versionResult.exitCode != 0) {
    throw Exception('Failed to locate system Chrome.');
  }
  // The output looks like: Google Chrome 79.0.3945.36.
  final String output = versionResult.stdout as String;

  print('INFO: chrome version in use $output');

  // Version number such as 79.0.3945.36.
  try {
    final String versionAsString = output.trim().split(' ').last;
    final String majorVersion = versionAsString.split('.')[0];
    return int.parse(majorVersion);
  } catch (e) {
    throw Exception(
        'Was expecting a version of the form Google Chrome 79.0.3945.36., '
        'received $output');
  }
}

/// Find Google Chrome App on Mac.
Future<String> _findChromeExecutableOnMac() async {
  io.Directory chromeDirectory = io.Directory('/Applications')
      .listSync()
      .whereType<io.Directory>()
      .firstWhere(
        (d) => path.basename(d.path).endsWith('Chrome.app'),
        orElse: () => throw Exception('Failed to locate system Chrome'),
      );

  final io.File chromeExecutableDir = io.File(
      path.join(chromeDirectory.path, 'Contents', 'MacOS', 'Google Chrome'));

  return chromeExecutableDir.path;
}
