// 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:convert' show json;
import 'dart:io';

import 'package:path/path.dart' as pathlib;
import 'package:yaml/yaml.dart';

import 'environment.dart';
import 'utils.dart';

/// Rolls CanvasKit to the version specified in `dev/canvaskit_lock.yaml`.
///
/// Detailed instructions for how to use this script can be found in
/// `lib/web_ui/README.md`.
Future<void> main(List<String> args) async {
  final String canvaskitVersion = _readCanvaskitVersion();
  print('Rolling CanvasKit to version $canvaskitVersion');

  final Directory canvaskitDirectory = await Directory.systemTemp.createTemp('canvaskit-roll-$canvaskitVersion-');
  print('Will use ${canvaskitDirectory.path} as staging directory.');

  final String baseUrl = 'https://unpkg.com/canvaskit-wasm@$canvaskitVersion/bin/';
  print('Downloading CanvasKit from $baseUrl');
  final HttpClient client = HttpClient();
  for (final String assetPath in _canvaskitAssets) {
    final String assetUrl = '$baseUrl/$assetPath';
    final File assetFile = File(pathlib.joinAll(<String>[
      canvaskitDirectory.path,
      'canvaskit',
      ...assetPath.split('/'), // so it's compatible with Windows
    ]));
    await assetFile.parent.create(recursive: true);
    final HttpClientRequest request = await client.getUrl(Uri.parse(assetUrl));
    final HttpClientResponse response = await request.close();
    final IOSink fileSink = assetFile.openWrite();
    await response.pipe(fileSink);
  }
  client.close();

  final File cipdConfigFile = File(pathlib.join(
    canvaskitDirectory.path,
    'cipd.yaml',
  ));
  await cipdConfigFile.writeAsString('''
package: flutter/web/canvaskit_bundle
description: A build of CanvasKit bundled with Flutter Web apps
data:
  - dir: canvaskit
''');

  print('Uploading to CIPD');
  await runProcess('cipd', <String>[
    'create',
    '--tag=version:$canvaskitVersion',
    '--pkg-def=cipd.yaml',
    '--json-output=result.json',
  ], workingDirectory: canvaskitDirectory.path);

  final Map<String, dynamic> cipdResult = json.decode(File(pathlib.join(
    canvaskitDirectory.path,
    'result.json',
  )).readAsStringSync()) as Map<String, dynamic>;
  final String cipdInstanceId = cipdResult['result']['instance_id'] as String;

  print('CIPD instance information:');
  final String cipdInfo = await evalProcess('cipd', <String>[
    'describe',
    'flutter/web/canvaskit_bundle',
    '--version=$cipdInstanceId',
  ], workingDirectory: canvaskitDirectory.path);
  print(cipdInfo.trim().split('\n').map((String line) => ' • $line').join('\n'));

  print('Updating DEPS file');
  await _updateDepsFile(cipdInstanceId);
  await _updateCanvaskitInitializationCode(canvaskitVersion);

  print('\nATTENTION: the roll process is not complete yet.');
  print('Last step: for the roll to take effect submit an engine pull request from local git changes.');
}

const List<String> _canvaskitAssets = <String>[
  'canvaskit.js',
  'canvaskit.wasm',
  'profiling/canvaskit.js',
  'profiling/canvaskit.wasm',
];

String _readCanvaskitVersion() {
  final YamlMap canvaskitLock = loadYaml(File(pathlib.join(
    environment.webUiDevDir.path,
    'canvaskit_lock.yaml',
  )).readAsStringSync()) as YamlMap;
  return canvaskitLock['canvaskit_version'] as String;
}

Future<void> _updateDepsFile(String cipdInstanceId) async {
  final File depsFile = File(pathlib.join(
    environment.flutterDirectory.path,
    'DEPS',
  ));

  final String originalDepsCode = await depsFile.readAsString();
  final List<String> rewrittenDepsCode = <String>[];
  const String kCanvasKitDependencyKeyInDeps = '\'canvaskit_cipd_instance\': \'';
  bool canvaskitDependencyFound = false;
  for (final String line in originalDepsCode.split('\n')) {
    if (line.trim().startsWith(kCanvasKitDependencyKeyInDeps)) {
      canvaskitDependencyFound = true;
      rewrittenDepsCode.add(
        "  'canvaskit_cipd_instance': '$cipdInstanceId',",
      );
    } else {
      rewrittenDepsCode.add(line);
    }
  }

  if (!canvaskitDependencyFound) {
    stderr.writeln(
      'Failed to update the DEPS file.\n'
      'Could not to locate CanvasKit dependency in the DEPS file. Make sure the '
      'DEPS file contains a line like this:\n'
      '\n'
      '  \'canvaskit_cipd_instance\': \'SOME_VALUE\','
    );
    exit(1);
  }

  await depsFile.writeAsString(rewrittenDepsCode.join('\n'));
}

Future<void> _updateCanvaskitInitializationCode(String canvaskitVersion) async {
  const String kCanvasKitVersionKey = 'const String canvaskitVersion';
  const String kPathToInitializationCode = 'lib/src/engine/canvaskit/initialization.dart';
  final File initializationFile = File(pathlib.join(
    environment.webUiRootDir.path,
    kPathToInitializationCode,
  ));
  final String originalInitializationCode = await initializationFile.readAsString();

  final List<String> rewrittenCode = <String>[];
  bool canvaskitVersionFound = false;
  for (final String line in originalInitializationCode.split('\n')) {
    if (line.trim().startsWith(kCanvasKitVersionKey)) {
      canvaskitVersionFound = true;
      rewrittenCode.add(
        "const String canvaskitVersion = '$canvaskitVersion';",
      );
    } else {
      rewrittenCode.add(line);
    }
  }

  if (!canvaskitVersionFound) {
    stderr.writeln(
      'Failed to update CanvasKit version in $kPathToInitializationCode.\n'
      'Could not to locate the constant that defines the version. Make sure the '
      '$kPathToInitializationCode file contains a line like this:\n'
      '\n'
      'const String canvaskitVersion = \'VERSION\';'
    );
    exit(1);
  }

  await initializationFile.writeAsString(rewrittenCode.join('\n'));
}
