// Copyright (c) 2023, 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:io';

import 'package:cli_config/cli_config.dart';
import 'package:intl/intl.dart';

class BisectionConfig {
  /// A way to identify this bisection.
  ///
  /// Used for log names etc.
  final String name;

  static const String _nameKey = 'name';

  /// Hash of the first commit.
  final String start;

  static const String _startKey = 'start';

  /// Hash of the last commit.
  final String end;

  static const String _endKey = 'end';

  /// The commands to run.
  ///
  /// Typically a `python3 tools/test.py --build [...]`.
  ///
  /// Commands are run in [sdkPath] as working directory.
  final List<String> testCommands;

  static const String _testCommandsKey = 'test_command';

  /// The pattern to recognize in the stdout or stderr of the last item in
  /// [testCommands].
  final String failureString;

  static const String _failureStringKey = 'failure_string';

  // This will likely be extended later to support regexes.
  Pattern get failurePattern => failureString.toPattern();

  /// The SDK checkout to use for bisecting.
  ///
  /// This will modify the SDK checkout!
  ///
  /// Will be created if it doesn't exist.
  final Uri sdkPath;

  static const _sdkPathKey = 'sdk_path';

  BisectionConfig({
    required this.name,
    required this.start,
    required this.end,
    required this.testCommands,
    required this.sdkPath,
    required this.failureString,
  });

  factory BisectionConfig.fromConfig(Config config) {
    final testCommands = config.stringList(_testCommandsKey);
    final name = config.optionalString(_nameKey) ??
        '${DateFormat('yyyyMMdd').format(DateTime.now())}_'
            '${testCommands.last.split(' ').last.split('/').last}';
    final sdkPath = config.optionalPath(_sdkPathKey, mustExist: true) ??
        Directory.current.uri;
    return BisectionConfig(
      name: name,
      start: config.string(_startKey),
      end: config.string(_endKey),
      testCommands: testCommands,
      sdkPath: sdkPath,
      failureString: config.string(_failureStringKey),
    );
  }

  Map<String, Object> asMap() => {
        _startKey: start,
        _endKey: end,
        _testCommandsKey: testCommands,
        _failureStringKey: failureString,
        _sdkPathKey: sdkPath.toFilePath(),
        _nameKey: name,
      };

  @override
  String toString() {
    return 'BisectionConfig(${asMap()})';
  }

  static final BisectionConfig _example = BisectionConfig(
    name: '20230712_package_resolve_test',
    start: '23f41452',
    end: '2c97bd78',
    testCommands: [
      'python3 tools/test.py --build -n dartk-linux-debug-x64 lib/isolate/package_resolve_test',
    ],
    sdkPath: Directory.current.uri,
    failureString: "Error: The argument type 'String' can't "
        "be assigned to the parameter type 'Uri'.",
  );

  static const _argumentDescriptions = {
    _startKey: 'The commit has at the start of the commit range.',
    _endKey: 'The commit has at the end of the commit range.',
    _testCommandsKey: '''The command(s) to run to reproduce the failure.
Typically this is "python3 tools/test.py --build [...]"
This should be within quotes when passed in terminal because of spaces.
This command can be supplied multiple times to run multiple commands to
reproduce a failure.
''',
    _failureStringKey: '''A string from the failing output.
Regexes are not yet supported.
This should be within quotes when passed in terminal when containing spaces.
''',
    _sdkPathKey: '''The SDK path is optional.
The SDK path defaults to the current working directory.
''',
    _nameKey: '''The name is optional.
The name defaults to the current date and the recognized test name.
The name is used for distinguishing logs.
''',
  };

  static String helpMessage() {
    final exampleArguments = _example.asMap().entries.map((e) {
      var value = e.value;
      if (value is List) {
        value = value.first as String;
      }
      if ((value as String).contains(' ')) {
        value = '"$value"';
      }
      return '-D${e.key}=$value';
    }).join(' ');
    const padding = _failureStringKey.length;
    final descriptions = _argumentDescriptions.entries.map((e) {
      final value = e.value
          .split('\n')
          .map((l) => '${' ' * (padding + 3)}$l')
          .join('\n')
          .trim();
      return '${e.key.padRight(padding)} : $value';
    }).join('\n');
    return '''
Usage: tools/bisect.dart $exampleArguments

This script starts a bisection in the provided SDK path.

It will write logs to .dart_tool/bisect_dart/.

$descriptions
''';
  }
}

extension on String {
  RegExp toPattern() => RegExp(RegExp.escape(this));
}
