// 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:yaml/yaml.dart' as y;

// This file contains classes for parsing information about CI configuration
// from the .ci.yaml file at the root of the flutter/engine repository.
// The meanings of the sections and fields are documented at:
//
// https://github.com/flutter/cocoon/blob/main/CI_YAML.md
//
// The classes here don't parse every possible field, but rather only those that
// are useful for working locally in the engine repo.

const String _targetsField = 'targets';
const String _nameField = 'name';
const String _recipeField = 'recipe';
const String _propertiesField = 'properties';
const String _configNameField = 'config_name';

/// A class containing the information deserialized from the .ci.yaml file.
///
/// The file contains three sections. "enabled_branches", "platform_properties",
/// and "targets". The "enabled_branches" section is not meaningful when working
/// locally. The configurations listed in the "targets" section inherit
/// properties listed in the "platform_properties" section depending on their
/// names. The configurations listed in the "targets" section are the names,
/// recipes, build configs, etc. of the builders in CI.
class CiConfig {
  /// Builds a [CiConfig] instance from parsed yaml data.
  ///
  /// If the yaml was malformed, then `CiConfig.valid` will be false, and
  /// `CiConfig.error` will be populated with an informative error message.
  /// Otherwise, `CiConfig.ciTargets` will contain a mapping from target name
  /// to [CiTarget] instance.
  factory CiConfig.fromYaml(y.YamlNode yaml) {
    if (yaml is! y.YamlMap) {
      final String error = yaml.span.message('Expected a map');
      return CiConfig._error(error);
    }
    final y.YamlMap ymap = yaml;
    final y.YamlNode? targetsNode = ymap.nodes[_targetsField];
    if (targetsNode == null) {
      final String error = ymap.span.message('Expected a "$_targetsField" key');
      return CiConfig._error(error);
    }
    if (targetsNode is! y.YamlList) {
      final String error = targetsNode.span.message(
        'Expected "$_targetsField" to be a list.',
      );
      return CiConfig._error(error);
    }
    final y.YamlList targetsList = targetsNode;

    final Map<String, CiTarget> result = <String, CiTarget>{};
    for (final y.YamlNode yamlTarget in targetsList.nodes) {
      final CiTarget target = CiTarget.fromYaml(yamlTarget);
      if (!target.valid) {
        return CiConfig._error(target.error);
      }
      result[target.name] = target;
    }

    return CiConfig._(ciTargets: result);
  }

  CiConfig._({
    required this.ciTargets,
  }) : error = null;

  CiConfig._error(
    this.error,
  ) : ciTargets = <String, CiTarget>{};

  /// Information about CI builder configurations, which .ci.yaml calls
  /// "targets".
  final Map<String, CiTarget> ciTargets;

  /// An error message when this instance is invalid.
  final String? error;

  /// Whether this is a valid instance.
  late final bool valid = error == null;
}

/// Information about the configuration of a builder on CI, which .ci.yaml
/// calls a "target".
class CiTarget {
  /// Builds a [CiTarget] from parsed yaml data.
  ///
  /// If the yaml was malformed then `CiTarget.valid` is false and
  /// `CiTarget.error` contains a useful error message. Otherwise, the other
  /// fields contain information about the target.
  factory CiTarget.fromYaml(y.YamlNode yaml) {
    if (yaml is! y.YamlMap) {
      final String error = yaml.span.message('Expected a map.');
      return CiTarget._error(error);
    }
    final y.YamlMap targetMap = yaml;
    final String? name = _stringOfNode(targetMap.nodes[_nameField]);
    if (name == null) {
      final String error = targetMap.span.message(
        'Expected map to contain a string value for key "$_nameField".',
      );
      return CiTarget._error(error);
    }

    final String? recipe = _stringOfNode(targetMap.nodes[_recipeField]);
    if (recipe == null) {
      final String error = targetMap.span.message(
        'Expected map to contain a string value for key "$_recipeField".',
      );
      return CiTarget._error(error);
    }

    final y.YamlNode? propertiesNode = targetMap.nodes[_propertiesField];
    if (propertiesNode == null) {
      final String error = targetMap.span.message(
        'Expected map to contain a string value for key "$_propertiesField".',
      );
      return CiTarget._error(error);
    }
    final CiTargetProperties properties = CiTargetProperties.fromYaml(
      propertiesNode,
    );
    if (!properties.valid) {
      return CiTarget._error(properties.error);
    }

    return CiTarget._(
      name: name,
      recipe: recipe,
      properties: properties,
    );
  }

  CiTarget._({
    required this.name,
    required this.recipe,
    required this.properties,
  }) : error = null;

  CiTarget._error(
    this.error,
  ) : name = '',
      recipe = '',
      properties = CiTargetProperties._error('Invalid');

  /// The name of the builder in CI.
  final String name;

  /// The CI recipe used to run the build.
  final String recipe;

  /// The properties of the build or builder.
  final CiTargetProperties properties;

  /// An error message when this instance is invalid.
  final String? error;

  /// Whether this is a valid instance.
  late final bool valid = error == null;
}

/// Various properties of a [CiTarget].
class CiTargetProperties {
  /// Builds a [CiTargetProperties] instance from parsed yaml data.
  ///
  /// If the yaml was malformed then `CiTargetProperties.valid` is false and
  /// `CiTargetProperties.error` contains a useful error message. Otherwise, the
  /// other fields contain information about the target properties.
  factory CiTargetProperties.fromYaml(y.YamlNode yaml) {
    if (yaml is! y.YamlMap) {
      final String error = yaml.span.message(
        'Expected "$_propertiesField" to be a map.',
      );
      return CiTargetProperties._error(error);
    }
    final y.YamlMap propertiesMap = yaml;
    final String? configName = _stringOfNode(
      propertiesMap.nodes[_configNameField],
    );
    return CiTargetProperties._(
      configName: configName ?? '',
    );
  }

  CiTargetProperties._({
    required this.configName,
  }) : error = null;

  CiTargetProperties._error(
    this.error,
  ) : configName = '';

  /// The name of the build configuration. If the containing [CiTarget] instance
  /// is using the engine_v2 recipes, then this name is the same as the name
  /// of the build config json file under ci/builders.
  final String configName;

  /// An error message when this instance is invalid.
  final String? error;

  /// Whether this is a valid instance.
  late final bool valid = error == null;
}

String? _stringOfNode(y.YamlNode? stringNode) {
  if (stringNode == null) {
    return null;
  }
  if (stringNode is! y.YamlScalar) {
    return null;
  }
  final y.YamlScalar stringScalar = stringNode;
  if (stringScalar.value is! String) {
    return null;
  }
  return stringScalar.value as String;
}
