// 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 String _LookUpFunction(Configuration configuration);
typedef bool _BoolLookUpFunction(Configuration configuration);

// TODO(29756): Instead of synthesized negated variables like "unchecked",
// consider adding support for "!" to status expressions.
final _variables = {
  "analyzer": new _Variable.bool((c) => c.compiler == Compiler.dart2analyzer),
  "analyzer_use_fasta_parser":
      new _Variable.bool((c) => c.useAnalyzerFastaParser),
  "arch": new _Variable((c) => c.architecture.name, Architecture.names),
  "browser": new _Variable.bool((c) => c.runtime.isBrowser),
  "builder_tag": new _Variable((c) => c.builderTag ?? "", const []),
  "checked": new _Variable.bool((c) => c.isChecked),
  "compiler": new _Variable((c) => c.compiler.name, Compiler.names),
  "csp": new _Variable.bool((c) => c.isCsp),
  "dart2js_with_kernel": new _Variable.bool((c) => c.useDart2JSWithKernel),
  "dart2js_old_frontend": new _Variable.bool((c) => c.useDart2JSOldFrontend),
  "enable_asserts": new _Variable.bool((c) => c.useEnableAsserts),
  "fast_startup": new _Variable.bool((c) => c.useFastStartup),
  "fasta": new _Variable.bool((c) => c.usesFasta),
  "host_checked": new _Variable.bool((c) => c.isHostChecked),
  "host_unchecked": new _Variable.bool((c) => !c.isHostChecked),
  "hot_reload": new _Variable.bool((c) => c.hotReload),
  "hot_reload_rollback": new _Variable.bool((c) => c.hotReloadRollback),
  "ie": new _Variable.bool((c) => c.runtime.isIE),
  "jscl": new _Variable.bool((c) => c.runtime.isJSCommandLine),
  "minified": new _Variable.bool((c) => c.isMinified),
  "mode": new _Variable((c) => c.mode.name, Mode.names),
  "no_preview_dart_2": new _Variable.bool((c) => c.noPreviewDart2),
  "preview_dart_2": new _Variable.bool((c) => !c.noPreviewDart2),
  "runtime": new _Variable(_runtimeName, Runtime.names),
  "spec_parser": new _Variable.bool((c) => c.compiler == Compiler.specParser),
  "strong": new _Variable.bool(
      (c) => c.isStrong || c.compilerConfiguration.previewDart2),
  "system": new _Variable((c) => c.system.name, System.names),
  "use_sdk": new _Variable.bool((c) => c.useSdk)
};

/// Gets the name of the runtime as it appears in status files.
String _runtimeName(Configuration 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;
}

/// 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 Configuration _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].
  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].
  String lookUp(String name) {
    var variable = _variables[name];
    if (variable == null) {
      // This shouldn't happen since we validate variables before evaluating
      // expressions.
      throw new 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
/// [Configuration]
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(Configuration configuration) => _lookUp(configuration);
}
