// 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.

import 'dart:io' as io;

import 'package:args/args.dart';
import 'package:http/http.dart';
import 'package:path/path.dart' as path;

import 'browser_lock.dart';
import 'common.dart';
import 'utils.dart';

final ArgParser _argParser = ArgParser(allowTrailingOptions: false)
  ..addFlag(
    'dry-run',
    help: 'Whether or not to push changes to CIPD. When --dry-run is set, the '
          'script will download everything and attempt to prepare the bundle '
          'but will stop before publishing. When not set, the bundle will be '
          'published.',
    negatable: false,
  )..addFlag(
    'verbose',
    abbr: 'v',
    help: 'Enable verbose output.',
    negatable: false,
  );

late final bool dryRun;
late final bool verbose;

final Client _client = Client();

/// Rolls browser CIPD packages to the version specified in `browser_lock.yaml`.
///
/// Currently only rolls Chrome.
///
/// Chrome rolls are consumed by the "chrome_and_driver" and "chrome" LUCI recipes, here:
/// * https://cs.opensource.google/flutter/recipes/+/main:recipe_modules/flutter_deps/api.py;l=146
/// * https://cs.opensource.google/flutter/recipes/+/master:recipe_modules/web_util/api.py;l=22
///
/// Chromedriver is consumed by the same "chrome_and_driver" LUCI recipe, but also "chrome_driver":
/// * https://cs.opensource.google/flutter/recipes/+/master:recipe_modules/web_util/api.py;l=48
///
/// There's a small difference in the layout of the zip file coming from CIPD for the
/// Mac platform. In `Linux` and `Windows`, the chrome(.exe) executable is expected
/// to be placed directly in the root of the zip file.
///
/// However in `Mac`, the `Chromium.app` is expected to be placed inside of a
/// `chrome-mac` directory in the resulting zip file.
///
/// This script respects that historical quirk when building the CIPD packages.
/// In order for all the packages to be the same, the recipes listed above should
/// be made slightly smarter, so they can find the CHROME_EXECUTABLE in the right
/// place.
///
/// All platforms expect the "chromedriver" executable to be placed in the root
/// of the CIPD zip.
Future<void> main(List<String> args) async {
  try {
    processArgs(_argParser.parse(args));
    await _BrowserRoller().roll();
    io.exitCode = 0;
  } on FormatException catch (e) {
    print('''
Error! ${e.message}

Available options:

${_argParser.usage}
''');
    io.exitCode = 1;
  } finally {
    _client.close();
  }
}

// Initialize globals from the parsed command-line arguments.
void processArgs(ArgResults args) {
  dryRun = args['dry-run'] as bool;
  verbose = args['verbose'] as bool;
}

class _Platform {
  _Platform(this.os, this.arch, this.binding);

  final String os;
  final String arch;
  final PlatformBinding binding;

  String get name => '$os-$arch';
}

class _BrowserRoller {
  _BrowserRoller();

  final io.Directory _rollDir = io.Directory.systemTemp.createTempSync('browser-roll-');

  final List<_Platform> _platforms = <_Platform>[
    _Platform('linux', 'amd64', LinuxPlatformBinding()),
    _Platform('mac', 'amd64', Macx64PlatformBinding()),
    _Platform('mac', 'arm64', MacArmPlatformBinding()),
    _Platform('windows', 'amd64', WindowsPlatformBinding()),
  ];

  final BrowserLock _lock = BrowserLock();

  // Prints output when --verbose is set.
  void vprint(String out) {
    if (verbose) {
      print(out);
    }
  }

  // Roll Chromium and ChromeDriver for each of the Platforms.
  Future<void> roll() async {
    for (final _Platform platform in _platforms) {
      await _rollChromium(platform);
      await _rollChromeDriver(platform);
    }
    if (dryRun) {
      print('\nDry Run Done!\nNon-published roll artifacts kept here: ${_rollDir.path}\n');
    } else {
      // Clean-up
      vprint('\nDeleting temporary directory: ${_rollDir.path}');
      await _rollDir.delete(recursive: true);
      print('\nDone.\n');
    }
  }

  // Returns the contents for the CIPD config required to publish a new chromium package.
  String _getCipdChromiumConfig({
    required String package,
    required String majorVersion,
    required String buildId,
    required String root,
  }) {
    return '''
package: $package
description: Chromium $majorVersion (build $buildId) used for testing
preserve_writable: true
root: $root
data:
  - dir: .
''';
  }

  // Returns the contents for the CIPD config required to publish a new chromedriver package.
  String _getCipdChromedriverConfig({
    required String package,
    required String majorVersion,
    required String buildId,
    required String root,
  }) {
    return '''
package: $package
description: Chromedriver for Chromium $majorVersion (build $buildId) used for testing
preserve_writable: true
root: $root
data:
  - dir: .
''';
  }

  // Download a file from the internet, and put it in a temporary location.
  Future<io.File> _downloadTemporaryFile(String url) async {
    // Use the hash of the Url to temporarily store a file under tmp
    final io.File downloadedFile = io.File(path.join(
        io.Directory.systemTemp.path,
        'download_${url.hashCode.toRadixString(16)}',
      ));
    vprint('  Downloading [$url] into [${downloadedFile.path}]');
    final StreamedResponse download = await _client.send(
      Request('GET', Uri.parse(url)),
    );
    await download.stream.pipe(downloadedFile.openWrite());
    return downloadedFile;
  }

  // Unzips a `file` into a `destination` Directory (must exist).
  Future<void> _unzipAndDeleteFile(io.File zipFile, io.Directory destination) async {
    vprint('  Unzipping [${zipFile.path}] into [$destination]');
    await runProcess('unzip', <String>[
      if (!verbose) ...<String>[
        '-q',
      ],
      zipFile.path,
      '-d',
      destination.path,
    ]);
    vprint('  Deleting [${zipFile.path}]');
    await zipFile.delete();
  }

  // Write String `contents` to a file in `path`.
  //
  // This is used to write CIPD config files to disk.
  Future<io.File> _writeFile(String path, String contents) async {
    vprint('  Writing file [$path]');
    final io.File file = io.File(path, );
    await file.writeAsString(contents);
    return file;
  }

  // Locate the first subdirectory that contains more than one file under `root`.
  // (or one ".app" bundle for mac)
  //
  // When uncompressing files, unzip might create some extra directories, but it
  // seems that our scripts want our CIPD packages to contain everything in the root.
  Future<io.Directory?> _locateContentRoot(io.Directory root) async {
    final List<io.FileSystemEntity> children = root.listSync(followLinks: false);
    assert(children.isNotEmpty);
    if (root.path.toLowerCase().endsWith('.app')) {
      // We've gone inside the .app bundle of the mac version!
      return root.parent;
    }
    if (children.length == 1) {
      if (children.first is io.Directory) {
        return _locateContentRoot(children.first as io.Directory);
      } else {
        return root;
      }
    }
    return root;
  }

  // Runs a CIPD command to upload a package defined by its `config` file.
  Future<int> _uploadToCipd({
    required io.File config,
    required String version,
    required String buildId,
  }) {
    final String cipdCommand = dryRun ? 'pkg-build' : 'create';
    // CIPD won't fully shut up even in 'error' mode
    final String logLevel = verbose ? 'debug' : 'warning';
    vprint('  Running CIPD $cipdCommand');
    return runProcess('cipd', <String>[
      cipdCommand,
      '--pkg-def',
      path.basename(config.path),
      '--json-output',
      '${path.basenameWithoutExtension(config.path)}.json',
      '--log-level',
      logLevel,
      if (!dryRun) ...<String>[
        '--tag',
        'version:$version',
        '--ref',
        buildId,
      ],
      if (dryRun) ...<String>[
        '--out',
        '${path.basenameWithoutExtension(config.path)}.zip',
      ],
    ], workingDirectory: _rollDir.path);
  }

  // Determine if a `package` tagged with version:`versionTag` already exists in CIPD.
  Future<bool> _cipdKnowsPackageVersion({
    required String package,
    required String versionTag,
  }) async {
    // $ cipd search $package -tag version:$versionTag
    // Instances:
    //   $package:CIPD_PACKAGE_ID
    // or:
    // No matching instances.
    final String logLevel = verbose ? 'debug' : 'warning';
    vprint('  Searching for $package version:$versionTag in CIPD');
    final String stdout = await evalProcess('cipd', <String>[
      'search',
      package,
      '--tag',
      'version:$versionTag',
      '--log-level',
      logLevel,
    ], workingDirectory: _rollDir.path);

    return stdout.contains('Instances:') && stdout.contains(package);
  }

  // Downloads Chromium from the internet, packs it in the directory structure
  // that the LUCI script wants. The result of this will be then uploaded to CIPD.
  Future<void> _rollChromium(_Platform platform) async {
    final String chromeBuild = platform.binding.getChromeBuild(_lock.chromeLock);
    final String majorVersion = _lock.chromeLock.version;
    final String url = platform.binding.getChromeDownloadUrl(chromeBuild);
    final String cipdPackageName = 'flutter_internal/browsers/chrome/${platform.name}';
    final io.Directory platformDir = io.Directory(path.join(_rollDir.path, platform.name));
    print('\nRolling Chromium for ${platform.name} (version:$majorVersion, build $chromeBuild)');
    // Bail out if CIPD already has version:$majorVersion for this package!
    if (!dryRun && await _cipdKnowsPackageVersion(package: cipdPackageName, versionTag: majorVersion)) {
      print('  Skipping $cipdPackageName version:$majorVersion. Already uploaded to CIPD!');
      vprint('  Update  browser_lock.yaml  and use a different version value.');
      return;
    }

    await platformDir.create(recursive: true);
    vprint('  Created target directory [${platformDir.path}]');

    final io.File chromeDownload = await _downloadTemporaryFile(url);

    await _unzipAndDeleteFile(chromeDownload, platformDir);

    late String relativePlatformDirPath;
    // Preserve the `chrome-mac` directory when bundling, but remove it for win and linux.
    if (platform.os == 'mac') {
      relativePlatformDirPath = path.relative(platformDir.path, from: _rollDir.path);
    } else {
      final io.Directory? actualContentRoot = await _locateContentRoot(platformDir);
      assert(actualContentRoot != null);
      relativePlatformDirPath = path.relative(actualContentRoot!.path, from: _rollDir.path);
    }

    // Create the config manifest to upload to CIPD
    final io.File cipdConfigFile = await _writeFile(
        path.join(_rollDir.path, 'cipd.chromium.${platform.name}.yaml'),
        _getCipdChromiumConfig(
            package: cipdPackageName,
            majorVersion: majorVersion,
            buildId: chromeBuild,
            root: relativePlatformDirPath,
        ));
    // Run CIPD
    await _uploadToCipd(config: cipdConfigFile, version: majorVersion, buildId: chromeBuild);
  }

  // Downloads Chromedriver from the internet, packs it in the directory structure
  // that the LUCI script wants. The result of this will be then uploaded to CIPD.
  Future<void> _rollChromeDriver(_Platform platform) async {
    final String chromeBuild = platform.binding.getChromeBuild(_lock.chromeLock);
    final String majorVersion = _lock.chromeLock.version;
    final String url = platform.binding.getChromeDriverDownloadUrl(chromeBuild);
    final String cipdPackageName = 'flutter_internal/browser-drivers/chrome/${platform.name}';
    final io.Directory platformDir = io.Directory(path.join(_rollDir.path, '${platform.name}_driver'));
    print('\nRolling Chromedriver for ${platform.os}-${platform.arch} (version:$majorVersion, build $chromeBuild)');
    // Bail out if CIPD already has version:$majorVersion for this package!
    if (!dryRun && await _cipdKnowsPackageVersion(package: cipdPackageName, versionTag: majorVersion)) {
      print('  Skipping $cipdPackageName version:$majorVersion. Already uploaded to CIPD!');
      vprint('  Update  browser_lock.yaml  and use a different version value.');
      return;
    }

    await platformDir.create(recursive: true);
    vprint('  Created target directory [${platformDir.path}]');

    final io.File chromedriverDownload = await _downloadTemporaryFile(url);

    await _unzipAndDeleteFile(chromedriverDownload, platformDir);

    // Ensure the chromedriver executable is placed in the root of the bundle.
    final io.Directory? actualContentRoot = await _locateContentRoot(platformDir);
    assert(actualContentRoot != null);
    final String relativePlatformDirPath = path.relative(actualContentRoot!.path, from: _rollDir.path);

    // Create the config manifest to upload to CIPD
    final io.File cipdConfigFile = await _writeFile(
        path.join(_rollDir.path, 'cipd.chromedriver.${platform.name}.yaml'),
        _getCipdChromedriverConfig(
            package: cipdPackageName,
            majorVersion: majorVersion,
            buildId: chromeBuild,
            root: relativePlatformDirPath,
        ));
    // Run CIPD
    await _uploadToCipd(config: cipdConfigFile, version: majorVersion, buildId: chromeBuild);
  }
}
