// Copyright (c) 2018, 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:convert';
import 'dart:io';

import 'builder.dart';
import 'configuration.dart';

/// The manifest that defines the set of supported test [Configuration]s and
/// how they are run on the [Builders]s.
class TestMatrix {
  final List<Configuration> configurations;
  final List<Builder> builders;
  final List<String> branches;

  /// Reads a test matrix from the file at [path].
  static TestMatrix fromPath(String path) {
    var json = jsonDecode(File(path).readAsStringSync());
    return fromJson(json as Map<String, dynamic>);
  }

  static TestMatrix fromJson(Map<String, dynamic> json) {
    var configurationsJson =
        json["configurations"] as Map<String, dynamic>? ?? <String, dynamic>{};

    // Keep track of the configurations and which templates they were expanded
    // from.
    var configurations = <Configuration>[];

    configurationsJson.forEach((template, configurationJson) {
      var options = configurationJson["options"] ?? const <String, dynamic>{};

      for (var configuration in Configuration.expandTemplate(
          template, options as Map<String, dynamic>)) {
        for (var existing in configurations) {
          // Make sure the names don't collide.
          if (configuration.name == existing.name) {
            throw FormatException(
                'Configuration "${configuration.name}" already exists.');
          }

          // Make sure we don't have two equivalent configurations.
          if (configuration.optionsEqual(existing)) {
            throw FormatException(
                'Configuration "${configuration.name}" is identical to '
                '"${existing.name}".');
          }
        }

        configurations.add(configuration);
      }
    });

    var builderConfigurations = <Map>[...?json["builder_configurations"]];
    var builders = parseBuilders(builderConfigurations, configurations);
    var branches = <String>[...?json["branches"]];

    // Check that each configuration is tested on at most one builder.
    var testedOn = <Configuration, Builder>{};
    for (var builder in builders) {
      for (var configuration in builder.testedConfigurations) {
        var other = testedOn[configuration];
        if (other != null) {
          throw FormatException('Configuration "${configuration.name}" is '
              'tested on both "${builder.name}" and "${other.name}"');
        } else {
          testedOn[configuration] = builder;
        }
      }
    }

    return TestMatrix._(configurations, builders, branches);
  }

  TestMatrix._(this.configurations, this.builders, this.branches);
}
