// Copyright (c) 2017, 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 'package:status_file/environment.dart';

import 'configuration.dart';

typedef _LookUpFunction = String Function(TestConfiguration configuration);
typedef _BoolLookUpFunction = bool Function(TestConfiguration configuration);

final _variables = {
  "analyzer": _Variable.bool((c) => c.compiler == Compiler.dart2analyzer),
  "analyzer_use_fasta_parser": _Variable.bool((c) => c.useAnalyzerFastaParser),
  "arch": _Variable((c) => c.architecture.name, Architecture.names),
  "browser": _Variable.bool((c) => c.runtime.isBrowser),
  "builder_tag": _Variable((c) => c.builderTag, const []),
  "checked": _Variable.bool((c) => c.isChecked),
  "compiler": _Variable((c) => c.compiler.name, Compiler.names),
  "csp": _Variable.bool((c) => c.isCsp),
  "enable_asserts": _Variable.bool((c) => c.enableAsserts),
  "fasta": _Variable.bool((c) => c.usesFasta),
  "host_asserts": _Variable.bool((c) => c.enableHostAsserts),
  "hot_reload": _Variable.bool((c) => c.hotReload),
  "hot_reload_rollback": _Variable.bool((c) => c.hotReloadRollback),
  "jscl": _Variable.bool((c) => c.runtime.isJSCommandLine),
  "minified": _Variable.bool((c) => c.isMinified),
  "mode": _Variable((c) => c.mode.name, Mode.names),
  "qemu": _Variable.bool((c) => c.useQemu),
  "runtime": _Variable(_runtimeName, _runtimeNames),
  "sanitizer": _Variable((c) => c.sanitizer.name, Sanitizer.names),
  "simulator": _Variable.bool((c) => c.isSimulator),
  "spec_parser": _Variable.bool((c) => c.compiler == Compiler.specParser),
  "system": _Variable(_systemName, _systemNames),
  "use_sdk": _Variable.bool((c) => c.useSdk)
};

/// Gets the name of the runtime as it appears in status files.
String _runtimeName(TestConfiguration configuration) {
  // TODO(rnystrom): Handle "ff" being used as the name for firefox. We don't
  // want to make the Runtime itself use that as the name because it appears
  // elsewhere in test.dart and we want those other places to show "firefox".
  if (configuration.runtime == Runtime.firefox) return 'ff';

  return configuration.runtime.name;
}

List<String> _runtimeNames = ['ff', 'drt', ...Runtime.names];

/// Gets the name of the runtime as it appears in status files.
String _systemName(TestConfiguration configuration) {
  // Because we are getting rid of status files, we don't want to change all
  // of them to say "win" instead of "windows" and "mac" instead of "macos"
  if (configuration.system == System.win) return 'windows';
  if (configuration.system == System.mac) return 'macos';

  return configuration.system.name;
}

List<String> _systemNames = ['windows', 'macos', ...System.names];

/// Defines the variables that are available for use inside a status file
/// section header.
///
/// These mostly map to command line arguments with the same name, though this
/// is only a subset of the full set of command line arguments.
class ConfigurationEnvironment implements Environment {
  /// The configuration where variable data is found.
  final TestConfiguration _configuration;

  ConfigurationEnvironment(this._configuration);

  /// Validates that the variable with [name] exists and can be compared
  /// against [value].
  ///
  /// If any errors are found, adds them to [errors].
  @override
  void validate(String name, String value, List<String> errors) {
    var variable = _variables[name];
    if (variable == null) {
      errors.add('Unknown variable "$name".');
      return;
    }

    // The "builder_tag" variable doesn't have an enumerated set of values.
    if (variable.allowedValues.isEmpty) return;

    if (!variable.allowedValues.contains(value)) {
      errors.add(
          'Variable "$name" cannot have value "$value". Allowed values are:\n'
          '${variable.allowedValues.join(', ')}.');
    }
  }

  /// Looks up the value of the variable with [name].
  @override
  String lookUp(String name) {
    var variable = _variables[name];
    if (variable == null) {
      // This shouldn't happen since we validate variables before evaluating
      // expressions.
      throw ArgumentError('Unknown variable "$variable".');
    }

    return variable.lookUp(_configuration);
  }
}

// TODO(rnystrom): There's some overlap between these and _Option in
// options.dart. Unify?
/// Describes a variable name whose value can be tested in a status file.
///
/// Each variable is an enumerated string type that only accepts a limited range
/// of values. Each instance of this class defines one variable, the values it
/// permits, and the logic needed to look up the variable's value from a
/// [TestConfiguration]
class _Variable {
  final _LookUpFunction _lookUp;
  final List<String> allowedValues;

  _Variable(this._lookUp, Iterable<String> allowed)
      : allowedValues = allowed.toList();

  /// Creates a Boolean variable with allowed values "true" and "false".
  _Variable.bool(_BoolLookUpFunction lookUp)
      : _lookUp = ((configuration) => lookUp(configuration).toString()),
        allowedValues = const ["true", "false"];

  String lookUp(TestConfiguration configuration) => _lookUp(configuration);
}
