// 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 'package:meta/meta.dart';
import 'package:platform/platform.dart';

// This library parses Engine builder config data out of the "Engine v2" build
// config JSON files with the format described at:
//   https://github.com/flutter/engine/blob/main/ci/builders/README.md

/// Base class for all nodes in the build config.
sealed class BuildConfigBase {
  BuildConfigBase(this.errors);

  /// Accumulated errors. Non-null and non-empty when a node is invalid.
  final List<String>? errors;

  /// Whether there were errors when loading the data for this node.
  late final bool valid = errors == null;

  /// Returns an empty list when the object is valid, and errors when it is not.
  /// Subclasses with more data to check for validity should override this
  /// method and add `super.check(path)` to the returned list.
  @mustCallSuper
  List<String> check(String path) {
    if (valid) {
      return <String>[];
    }
    return errors!.map((String s) => '$path: $s').toList();
  }
}

/// The builder configuration is a json file containing a list of builds, tests,
/// generators and archives.
///
/// Each builder config file contains a top-level json map with the following
/// fields:
/// {
///    "builds": [],
///    "tests": [],
///    "generators": {
///      "tasks": []
///    },
///    "archives": []
/// }
final class BuilderConfig extends BuildConfigBase {
  /// Load build configuration data into an instance of this class.
  ///
  /// [path] should be the file system path to the file that the JSON data comes
  /// from. [map] must be the JSON data returned by e.g. `JsonDecoder.convert`.
  factory BuilderConfig.fromJson({
    required String path,
    required Map<String, Object?> map,
  }) {
    final List<String> errors = <String>[];

    // Parse the "builds" field.
    final List<Build>? builds = objListOfJson<Build>(
      map,
      'builds',
      errors,
      Build.fromJson,
    );

    // Parse the "tests" field.
    final List<GlobalTest>? tests = objListOfJson<GlobalTest>(
      map,
      'tests',
      errors,
      GlobalTest.fromJson,
    );

    // Parse the "generators" field.
    final List<TestTask>? generators;
    if (map['generators'] == null) {
      generators = <TestTask>[];
    } else if (map['generators'] is! Map<String, Object?>) {
      appendTypeError(map, 'generators', 'map', errors);
      generators = null;
    } else {
      generators = objListOfJson(
        map['generators']! as Map<String, Object?>,
        'tasks',
        errors,
        TestTask.fromJson,
      );
    }

    // Parse the "archives" field.
    final List<GlobalArchive>? archives = objListOfJson<GlobalArchive>(
      map,
      'archives',
      errors,
      GlobalArchive.fromJson,
    );

    if (builds == null ||
        tests == null ||
        generators == null ||
        archives == null) {
      return BuilderConfig._invalid(path, errors);
    }
    return BuilderConfig._(path, builds, tests, generators, archives);
  }

  BuilderConfig._(
    this.path,
    this.builds,
    this.tests,
    this.generators,
    this.archives,
  ) : super(null);

  BuilderConfig._invalid(this.path, super.errors)
      : builds = <Build>[],
        tests = <GlobalTest>[],
        generators = <TestTask>[],
        archives = <GlobalArchive>[];

  /// The path to the JSON file.
  final String path;

  /// A list of independent builds that have no dependencies among them. They
  /// can run in parallel if need be.
  final List<Build> builds;

  /// A list of tests. The tests may have dependencies on one or more of the
  /// builds.
  final List<GlobalTest> tests;

  /// A list of generator tasks that produce additional artifacts, which may
  /// depend on the output of one or more builds.
  final List<TestTask> generators;

  /// A description of the upload instructions for the artifacts produced by
  /// the global generators.
  final List<GlobalArchive> archives;

  @override
  List<String> check(String path) {
    final List<String> errors = <String>[];
    errors.addAll(super.check(path));
    for (int i = 0; i < builds.length; i++) {
      final Build build = builds[i];
      errors.addAll(build.check('$path/builds[$i]'));
    }
    for (int i = 0; i < tests.length; i++) {
      final GlobalTest test = tests[i];
      errors.addAll(test.check('$path/tests[$i]'));
    }
    for (int i = 0; i < generators.length; i++) {
      final TestTask task = generators[i];
      errors.addAll(task.check('$path/generators/tasks[$i]'));
    }
    for (int i = 0; i < archives.length; i++) {
      final GlobalArchive archive = archives[i];
      errors.addAll(archive.check('$path/archives[$i]'));
    }
    return errors;
  }

  /// Returns true if any of the [Build]s it contains can run on
  /// `platform`, and false otherwise.
  bool canRunOn(Platform platform) {
    return builds.any((Build b) => b.canRunOn(platform));
  }
}

/// A "build" is a dictionary with a gn command, a ninja command, zero or more
/// generator commands, zero or more local tests, zero or more local generators
/// and zero or more output artifacts.
///
/// "builds" contains a list of maps with fields like:
/// {
///   "name": "",
///   "description": "",
///   "gn": [""],
///   "ninja": {},
///   "tests": [],
///   "generators": {
///     "tasks": []
///   }, (optional)
///   "archives": [],
///   "drone_dimensions": [""],
///   "gclient_variables": {}
/// }
final class Build extends BuildConfigBase {
  factory Build.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? description = stringOfJson(map, 'description', errors);
    final List<String>? gn = stringListOfJson(map, 'gn', errors);
    final List<BuildTest>? tests = objListOfJson(
      map,
      'tests',
      errors,
      BuildTest.fromJson,
    );
    final List<BuildArchive>? archives = objListOfJson(
      map,
      'archives',
      errors,
      BuildArchive.fromJson,
    );
    final List<String>? droneDimensions = stringListOfJson(
      map,
      'drone_dimensions',
      errors,
    );

    final BuildNinja? ninja;
    if (map['ninja'] == null) {
      ninja = BuildNinja.nop();
    } else if (map['ninja'] is! Map<String, Object?>) {
      ninja = null;
    } else {
      ninja = BuildNinja.fromJson(map['ninja']! as Map<String, Object?>);
    }
    if (ninja == null) {
      appendTypeError(map, 'ninja', 'map', errors);
    }

    final List<BuildTask>? generators;
    if (map['generators'] == null) {
      generators = <BuildTask>[];
    } else if (map['generators'] is! Map<String, Object?>) {
      appendTypeError(map, 'generators', 'map', errors);
      generators = null;
    } else {
      generators = objListOfJson(
        map['generators']! as Map<String, Object?>,
        'tasks',
        errors,
        BuildTask.fromJson,
      );
    }

    final Map<String, Object?>? gclientVariables;
    if (map['gclient_variables'] == null) {
      gclientVariables = <String, Object?>{};
    } else if (map['gclient_variables'] is! Map<String, Object?>) {
      gclientVariables = null;
    } else {
      gclientVariables = map['gclient_variables']! as Map<String, Object?>;
    }
    if (gclientVariables == null) {
      appendTypeError(map, 'gclient_variables', 'map', errors);
    }

    if (name == null ||
        description == null ||
        gn == null ||
        ninja == null ||
        archives == null ||
        tests == null ||
        generators == null ||
        droneDimensions == null ||
        gclientVariables == null) {
      return Build._invalid(errors);
    }
    return Build._(
      name,
      description,
      gn,
      ninja,
      tests,
      generators,
      archives,
      droneDimensions,
      gclientVariables,
    );
  }

  Build._(
    this.name,
    this.description,
    this.gn,
    this.ninja,
    this.tests,
    this.generators,
    this.archives,
    this.droneDimensions,
    this.gclientVariables,
  ) : super(null);

  Build._invalid(super.errors)
      : name = '',
        description = '',
        gn = <String>[],
        ninja = BuildNinja.nop(),
        tests = <BuildTest>[],
        generators = <BuildTask>[],
        archives = <BuildArchive>[],
        droneDimensions = <String>[],
        gclientVariables = <String, Object?>{};

  /// The name of the build which may also be used to reference it as a
  /// depdendency of a global test.
  final String name;

  /// The human-readable description of what a build accomplishes.
  final String description;

  /// The parameters to pass to `flutter/tools/gn` to configure the build.
  final List<String> gn;

  /// The data to form the ninja command to perform the build.
  final BuildNinja ninja;

  /// The list of tests that can be run after the ninja build is finished.
  final List<BuildTest> tests;

  /// A list of other tasks that may generate new artifacts after the ninja
  /// build is finished.
  final List<BuildTask> generators;

  /// Upload instructions for the artifacts produced by the build.
  final List<BuildArchive> archives;

  /// A list 'key=value' strings that are used to select the bot where this
  /// build will be running.
  final List<String> droneDimensions;

  /// A dictionary with variables included in the `custom_vars` section of the
  /// .gclient file before `gclient sync` is run.
  final Map<String, Object?> gclientVariables;

  /// Returns true if platform is capable of executing this build and false
  /// otherwise.
  bool canRunOn(Platform platform) => _canRunOn(droneDimensions, platform);

  @override
  List<String> check(String path) {
    final List<String> errors = <String>[];
    errors.addAll(super.check(path));
    errors.addAll(ninja.check('$path/ninja'));
    for (int i = 0; i < tests.length; i++) {
      final BuildTest test = tests[i];
      errors.addAll(test.check('$path/tests[$i]'));
    }
    for (int i = 0; i < generators.length; i++) {
      final BuildTask task = generators[i];
      errors.addAll(task.check('$path/generators/tasks[$i]'));
    }
    for (int i = 0; i < archives.length; i++) {
      final BuildArchive archive = archives[i];
      errors.addAll(archive.check('$path/archives[$i]'));
    }
    return errors;
  }
}

/// "builds" -> "ninja" contains a map with fields like:
/// {
///   "config": "",
///   "targets": [""]
/// },
final class BuildNinja extends BuildConfigBase {
  factory BuildNinja.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? config = stringOfJson(map, 'config', errors);
    final List<String>? targets = stringListOfJson(map, 'targets', errors);
    if (config == null || targets == null) {
      return BuildNinja._invalid(errors);
    }
    return BuildNinja._(config, targets);
  }

  BuildNinja._(this.config, this.targets) : super(null);

  BuildNinja._invalid(super.errors)
      : config = '',
        targets = <String>[];

  BuildNinja.nop()
      : config = '',
        targets = <String>[],
        super(null);

  /// The name of the configuration created by gn.
  ///
  /// This is also the subdirectory of the `out/` directory where the build
  /// output will go.
  final String config;

  /// The ninja targets to build.
  final List<String> targets;
}

/// "builds" -> "tests" contains a list of maps with fields like:
/// {
///  "language": "",
///  "name": "",
///  "parameters": [""],
///  "script": "",
///  "contexts": [""]
/// }
final class BuildTest extends BuildConfigBase {
  factory BuildTest.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? language = stringOfJson(map, 'language', errors);
    final String? script = stringOfJson(map, 'script', errors);
    final List<String>? parameters = stringListOfJson(
      map,
      'parameters',
      errors,
    );
    final List<String>? contexts = stringListOfJson(
      map,
      'contexts',
      errors,
    );
    if (name == null ||
        language == null ||
        script == null ||
        parameters == null ||
        contexts == null) {
      return BuildTest._invalid(errors);
    }
    return BuildTest._(name, language, script, parameters, contexts);
  }

  BuildTest._(
    this.name,
    this.language,
    this.script,
    this.parameters,
    this.contexts,
  ) : super(null);

  BuildTest._invalid(super.errors)
      : name = '',
        language = '',
        script = '',
        parameters = <String>[],
        contexts = <String>[];

  /// The human readable description of the test.
  final String name;

  /// The executable used to run the script.
  final String language;

  /// The path to the script to execute relative to the checkout directory.
  final String script;

  /// Flags or parameters passed to the script.
  ///
  /// Parameters accept magic environment variables (placeholders replaced
  /// before executing the test). Magic environment variables have the following
  /// limitations: only ${FLUTTER_LOGS_DIR} is currently supported and it needs
  /// to be used alone within the parameter string(e.g. ["${FLUTTER_LOGS_DIR}"]
  /// is OK but ["path=${FLUTTER_LOGS_DIR}"] is not).
  final List<String> parameters;

  /// A list of available contexts to add to the text execution step.
  ///
  /// Two contexts are supported: "android_virtual_device" and
  /// "metric_center_token".
  final List<String> contexts;
}

/// "builds" -> "generators" is a map containing a single property "tasks",
/// which is a list of maps with fields like:
/// {
///   "name": "",
///   "parameters": [""],
///   "scripts": [""],
///   "language": ""
/// }
///
/// The semantics of this task are that each script in the list of scripts is
/// run in sequence by appending the same parameter list to each one.
final class BuildTask extends BuildConfigBase {
  factory BuildTask.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? language = stringOfJson(map, 'language', errors);
    final List<String>? scripts = stringListOfJson(map, 'scripts', errors);
    final List<String>? parameters = stringListOfJson(
      map,
      'parameters',
      errors,
    );
    if (name == null ||
        language == null ||
        scripts == null ||
        parameters == null) {
      return BuildTask._invalid(errors);
    }
    return BuildTask._(name, language, scripts, parameters);
  }

  BuildTask._invalid(super.errors)
      : name = '',
        language = '',
        scripts = <String>[],
        parameters = <String>[];

  BuildTask._(this.name, this.language, this.scripts, this.parameters)
      : super(null);

  /// The human readable name of the step running the script.
  final String name;

  /// The script language executable to run the script. If empty it is assumed
  /// to be bash.
  final String language;

  /// A list of paths of scripts relative to the checkout directory. Each
  /// script is run in turn by appending the list of parameters to it.
  final List<String> scripts;

  /// The flags passed to the script. Paths referenced in the list are relative
  /// to the checkout directory.
  final List<String> parameters;
}

/// "builds" -> "archives" contains a list of maps with fields like:
/// {
///   "name": "",
///   "base_path": "",
///   "type": "",
///   "include_paths": [""],
///   "realm": ""
/// }
final class BuildArchive extends BuildConfigBase {
  factory BuildArchive.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? type = stringOfJson(map, 'type', errors);
    final String? basePath = stringOfJson(map, 'base_path', errors);
    final String? realm = stringOfJson(map, 'realm', errors);
    final List<String>? includePaths = stringListOfJson(
      map,
      'include_paths',
      errors,
    );
    if (name == null ||
        type == null ||
        basePath == null ||
        realm == null ||
        includePaths == null) {
      return BuildArchive._invalid(errors);
    }
    return BuildArchive._(name, type, basePath, realm, includePaths);
  }

  BuildArchive._invalid(super.error)
      : name = '',
        type = '',
        basePath = '',
        realm = '',
        includePaths = <String>[];

  BuildArchive._(
    this.name,
    this.type,
    this.basePath,
    this.realm,
    this.includePaths,
  ) : super(null);

  /// The name which may be referenced later as a dependency of global tests.
  final String name;

  /// The type of storage to use. Currently only “gcs” and “cas” are supported.
  final String type;

  /// The portion of the path to remove from the full path before uploading
  final String basePath;

  /// Either "production" or "experimental".
  final String realm;

  /// A list of strings with the paths to be uploaded to a given destination.
  final List<String> includePaths;
}

/// Global "tests" is a list of maps containing fields like:
/// {
///   "name": "",
///   "recipe": "",
///   "drone_dimensions": [""],
///   "dependencies": [""],
///   "tasks": [] (same format as above)
/// }
final class GlobalTest extends BuildConfigBase {
  factory GlobalTest.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? recipe = stringOfJson(map, 'recipe', errors);
    final List<String>? droneDimensions = stringListOfJson(
      map,
      'drone_dimensions',
      errors,
    );
    final List<String>? dependencies = stringListOfJson(
      map,
      'dependencies',
      errors,
    );
    final List<TestDependency>? testDependencies = objListOfJson(
      map,
      'test_dependencies',
      errors,
      TestDependency.fromJson,
    );
    final List<TestTask>? tasks = objListOfJson(
      map,
      'tasks',
      errors,
      TestTask.fromJson,
    );
    if (name == null ||
        recipe == null ||
        droneDimensions == null ||
        dependencies == null ||
        testDependencies == null ||
        tasks == null) {
      return GlobalTest._invalid(errors);
    }
    return GlobalTest._(
        name, recipe, droneDimensions, dependencies, testDependencies, tasks);
  }

  GlobalTest._invalid(super.errors)
      : name = '',
        recipe = '',
        droneDimensions = <String>[],
        dependencies = <String>[],
        testDependencies = <TestDependency>[],
        tasks = <TestTask>[];

  GlobalTest._(
    this.name,
    this.recipe,
    this.droneDimensions,
    this.dependencies,
    this.testDependencies,
    this.tasks,
  ) : super(null);

  /// The name that will be assigned to the sub-build.
  final String name;

  /// The recipe name to use if different than tester.
  final String recipe;

  /// A list of strings with key values to select the bot where the test will
  /// run.
  final List<String> droneDimensions;

  /// A list of build outputs required by the test.
  final List<String> dependencies;

  /// A list of dependencies required for the test to run.
  final List<TestDependency> testDependencies;

  /// A list of dictionaries representing scripts and parameters to run them
  final List<TestTask> tasks;

  /// Returns true if platform is capable of executing this build and false
  /// otherwise.
  bool canRunOn(Platform platform) => _canRunOn(droneDimensions, platform);

  @override
  List<String> check(String path) {
    final List<String> errors = <String>[];
    errors.addAll(super.check(path));
    for (int i = 0; i < testDependencies.length; i++) {
      final TestDependency testDependency = testDependencies[i];
      errors.addAll(testDependency.check('$path/test_dependencies[$i]'));
    }
    for (int i = 0; i < tasks.length; i++) {
      final TestTask task = tasks[i];
      errors.addAll(task.check('$path/tasks[$i]'));
    }
    return errors;
  }
}

/// A test dependency for a global test has fields like:
/// {
///   "dependency": "",
///   "version": ""
/// }
final class TestDependency extends BuildConfigBase {
  factory TestDependency.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? dependency = stringOfJson(map, 'dependency', errors);
    final String? version = stringOfJson(map, 'version', errors);
    if (dependency == null || version == null) {
      return TestDependency._invalid(errors);
    }
    return TestDependency._(dependency, version);
  }

  TestDependency._invalid(super.error)
      : dependency = '',
        version = '';

  TestDependency._(this.dependency, this.version) : super(null);

  /// A dependency from the list at:
  /// https://flutter.googlesource.com/recipes/+/refs/heads/main/recipe_modules/flutter_deps/api.py#75
  final String dependency;

  /// The CIPD version string of the dependency.
  final String version;
}

/// Task for a global generator and a global test.
/// {
///   "name": "",
///   "parameters": [""],
///   "script": "",
///   "language": ""
/// }
final class TestTask extends BuildConfigBase {
  factory TestTask.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? name = stringOfJson(map, 'name', errors);
    final String? language = stringOfJson(map, 'language', errors);
    final String? script = stringOfJson(map, 'script', errors);
    final int? maxAttempts =
        intOfJson(map, 'max_attempts', fallback: 1, errors);
    final List<String>? parameters = stringListOfJson(
      map,
      'parameters',
      errors,
    );
    if (name == null ||
        language == null ||
        script == null ||
        maxAttempts == null ||
        parameters == null) {
      return TestTask._invalid(errors);
    }
    return TestTask._(name, language, script, maxAttempts, parameters);
  }

  TestTask._invalid(super.error)
      : name = '',
        language = '',
        script = '',
        maxAttempts = 0,
        parameters = <String>[];

  TestTask._(
    this.name,
    this.language,
    this.script,
    this.maxAttempts,
    this.parameters,
  ) : super(null);

  /// The human readable name of the step running the script.
  final String name;

  /// The script language executable to run the script. If empty it is assumed
  /// to be bash.
  final String language;

  /// The script path relative to the checkout repository.
  final String script;

  /// The maximum number of failures to tolerate. The default is 1.
  final int maxAttempts;

  /// The flags passed to the script. Paths referenced in the list are relative
  /// to the checkout directory.
  final List<String> parameters;
}

/// The objects that populate the list of global archives have fields like:
/// {
///     "source": "out/debug/artifacts.zip",
///     "destination": "ios/artifacts.zip",
///     "realm": "production"
/// },
final class GlobalArchive extends BuildConfigBase {
  factory GlobalArchive.fromJson(Map<String, Object?> map) {
    final List<String> errors = <String>[];
    final String? source = stringOfJson(map, 'source', errors);
    final String? destination = stringOfJson(map, 'destination', errors);
    final String? realm = stringOfJson(map, 'realm', errors);
    if (source == null || destination == null || realm == null) {
      return GlobalArchive._invalid(errors);
    }
    return GlobalArchive._(source, destination, realm);
  }

  GlobalArchive._invalid(super.error)
      : source = '',
        destination = '',
        realm = '';

  GlobalArchive._(this.source, this.destination, this.realm) : super(null);

  /// The path of the artifact relative to the engine checkout.
  final String source;

  /// The destination folder in the storage bucket.
  final String destination;

  /// Which storage bucket the destination path is relative to.
  /// Either "production" or "experimental".
  final String realm;
}

bool _canRunOn(List<String> droneDimensions, Platform platform) {
  String? os;
  for (final String dimension in droneDimensions) {
    os ??= switch (dimension.split('=')) {
      ['os', 'Linux'] => Platform.linux,
      ['os', final String win] when win.startsWith('Windows') =>
        Platform.windows,
      ['os', final String mac] when mac.startsWith('Mac') => Platform.macOS,
      _ => null,
    };
  }
  return os == platform.operatingSystem;
}

void appendTypeError(
  Map<String, Object?> map,
  String field,
  String expected,
  List<String> errors, {
  Object? element,
}) {
  if (element == null) {
    final Type actual = map[field]!.runtimeType;
    errors.add(
      'For field "$field", expected type: $expected, actual type: $actual.',
    );
  } else {
    final Type actual = element.runtimeType;
    errors.add(
      'For element "$element" of "$field", '
      'expected type: $expected, actual type: $actual',
    );
  }
}

List<T>? objListOfJson<T>(
  Map<String, Object?> map,
  String field,
  List<String> errors,
  T Function(Map<String, Object?>) fn,
) {
  if (map[field] == null) {
    return <T>[];
  }
  if (map[field]! is! List<Object?>) {
    appendTypeError(map, field, 'list', errors);
    return null;
  }
  for (final Object? obj in map[field]! as List<Object?>) {
    if (obj is! Map<String, Object?>) {
      appendTypeError(map, field, 'map', errors);
      return null;
    }
  }
  return (map[field]! as List<Object?>)
      .cast<Map<String, Object?>>()
      .map<T>(fn)
      .toList();
}

List<String>? stringListOfJson(
  Map<String, Object?> map,
  String field,
  List<String> errors,
) {
  if (map[field] == null) {
    return <String>[];
  }
  if (map[field]! is! List<Object?>) {
    appendTypeError(map, field, 'list', errors);
    return null;
  }
  for (final Object? obj in map[field]! as List<Object?>) {
    if (obj is! String) {
      appendTypeError(map, field, element: obj, 'string', errors);
      return null;
    }
  }
  return (map[field]! as List<Object?>).cast<String>();
}

String? stringOfJson(
  Map<String, Object?> map,
  String field,
  List<String> errors,
) {
  if (map[field] == null) {
    return '<undef>';
  }
  if (map[field]! is! String) {
    appendTypeError(map, field, 'string', errors);
    return null;
  }
  return map[field]! as String;
}

int? intOfJson(
  Map<String, Object?> map,
  String field,
  List<String> errors, {
  int fallback = 0,
}) {
  if (map[field] == null) {
    return fallback;
  }
  if (map[field]! is! int) {
    appendTypeError(map, field, 'int', errors);
    return null;
  }
  return map[field]! as int;
}
