// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
// for details. 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:io';

void main() async {
  await Future.wait([_updateManifestJson(), _updateDevtoolsJs()]);
}

/// Adds the Googler extension key, updates the extension icon, and prefixes the
/// extension name with "[DEV]".
Future<void> _updateManifestJson() async {
  final manifestJson = File('dev_build/web/manifest.json');
  final extensionKeyTxt = File('extension_key.txt');
  final extensionKey = await extensionKeyTxt.exists()
      ? await extensionKeyTxt.readAsString()
      : null;
  return _transformDevFile(manifestJson, (line) {
    if (_matchesKey(line: line, key: 'name')) {
      return [
        _newKeyValue(
          oldLine: line,
          newKey: 'name',
          newValue: '[DEV] Dart Debug Extension',
        ),
        if (extensionKey != null)
          _newKeyValue(
            oldLine: line,
            newKey: 'key',
            newValue: extensionKey,
          ),
      ];
    }
    if (_matchesKey(line: line, key: 'default_icon')) {
      return [
        _newKeyValue(
          oldLine: line,
          newKey: 'default_icon',
          newValue: 'dart_dev.png',
        )
      ];
    }
    if (_matchesValue(line: line, value: 'background.js')) {
      return [
        _newKeyValue(
          oldLine: line,
          newKey: null,
          newValue: 'background.dart.js',
        )
      ];
    } else {
      return [line];
    }
  });
}

/// Prefixes the names of the panels that are added to Chrome DevTools with
/// "[DEV]".
Future<void> _updateDevtoolsJs() async {
  final devtoolsJs = File('dev_build/web/devtools.js');
  return _transformDevFile(devtoolsJs, (line) {
    final originalDebuggerLine = "const DEBUGGER_PANEL_NAME = 'Dart Debugger';";
    final modifiedDebuggerLine =
        "const DEBUGGER_PANEL_NAME = '[DEV] Dart Debugger';";
    final originalInspectorLine =
        "const INSPECTOR_PANEL_NAME = 'Flutter Inspector';";
    final modifiedInspectorLine =
        "const INSPECTOR_PANEL_NAME = '[DEV] Flutter Inspector';";
    if (_matchesLine(line: line, match: originalDebuggerLine)) {
      return [_newLine(oldLine: line, newLine: modifiedDebuggerLine)];
    }
    if (_matchesLine(line: line, match: originalInspectorLine)) {
      return [_newLine(oldLine: line, newLine: modifiedInspectorLine)];
    }
    return [line];
  });
}

Future<void> _transformDevFile(
    File devFile, List<String> Function(String) transformLine) async {
  final lines = devFile.readAsLinesSync();
  final newLines = <String>[];
  for (final line in lines) {
    newLines.addAll(transformLine(line));
  }
  final content = newLines.joinWithNewLine();
  return devFile.writeAsStringSync(content);
}

bool _matchesKey({required String line, required String key}) {
  return line.trimLeft().startsWith('"$key":');
}

bool _matchesValue({required String line, required String value}) {
  return line.trimRight().endsWith('"$value"') ||
      line.trimRight().endsWith('"$value",');
}

bool _matchesLine({required String line, required String match}) {
  return line.trim() == match;
}

String _newKeyValue({
  required String oldLine,
  String? newKey,
  String? newValue,
}) {
  final lineStart = oldLine.leftPadding();
  final key = newKey != null ? '"$newKey": ' : '';
  final value = newValue != null ? '"$newValue"' : '';
  final lineEnd = oldLine.trim().endsWith(',') ? ',' : '';
  return '$lineStart$key$value$lineEnd';
}

String _newLine({
  required String oldLine,
  required String newLine,
}) {
  final lineStart = oldLine.leftPadding();
  return '$lineStart$newLine';
}

extension LeftPaddingExtension on String {
  String leftPadding() {
    String padding = '';
    int idx = 0;
    while (idx < length && this[idx] == ' ') {
      padding += ' ';
      idx++;
    }
    return padding;
  }
}

extension JoinExtension on List<String> {
  String joinWithNewLine() {
    return '${join('\n')}\n';
  }
}
