// Copyright (c) 2016, 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:io';

import 'package:boolean_selector/boolean_selector.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart';
import 'package:yaml/yaml.dart';

import 'package:test_api/src/backend/operating_system.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/platform_selector.dart'; // ignore: implementation_imports
import 'package:test_api/src/frontend/timeout.dart'; // ignore: implementation_imports
import 'package:test_api/src/utils.dart'; // ignore: implementation_imports

import '../suite.dart';
import '../runtime_selection.dart';
import '../../util/io.dart';
import '../configuration.dart';
import 'custom_runtime.dart';
import 'load.dart' as self;
import 'reporters.dart';
import 'runtime_settings.dart';

/// A regular expression matching a Dart identifier.
///
/// This also matches a package name, since they must be Dart identifiers.
final _identifierRegExp = RegExp(r'[a-zA-Z_]\w*');

/// A regular expression matching allowed package names.
///
/// This allows dot-separated valid Dart identifiers. The dots are there for
/// compatibility with Google's internal Dart packages, but they may not be used
/// when publishing a package to pub.dev.
final _packageName =
    RegExp('^${_identifierRegExp.pattern}(\\.${_identifierRegExp.pattern})*\$');

/// Loads configuration information from a YAML file at [path].
///
/// See [loadFromString] for further documentation.
Configuration load(String path, {bool global = false}) {
  var source = File(path).readAsStringSync();
  return loadFromString(source, global: global, sourceUrl: p.toUri(path));
}

/// Loads configuration information from YAML formatted [source].
///
/// If [global] is `true`, this restricts the configuration file to only rules
/// that are supported globally.
///
/// If [sourceUrl] is provided then that will be set as the source url for
/// the yaml document.
///
/// Throws a [FormatException] if the configuration is invalid.
Configuration loadFromString(String source,
    {bool global = false, Uri sourceUrl}) {
  var document = loadYamlNode(source, sourceUrl: sourceUrl);

  if (document.value == null) return Configuration.empty;

  if (document is! Map) {
    throw SourceSpanFormatException(
        'The configuration must be a YAML map.', document.span, source);
  }

  var loader =
      _ConfigurationLoader(document as YamlMap, source, global: global);
  return loader.load();
}

/// A helper for [load] that tracks the YAML document.
class _ConfigurationLoader {
  /// The parsed configuration document.
  final YamlMap _document;

  /// The source string for [_document].
  ///
  /// Used for error reporting.
  final String _source;

  /// Whether this is parsing the global configuration file.
  final bool _global;

  /// Whether runner configuration is allowed at this level.
  final bool _runnerConfig;

  _ConfigurationLoader(this._document, this._source,
      {bool global = false, bool runnerConfig = true})
      : _global = global,
        _runnerConfig = runnerConfig;

  /// Loads the configuration in [_document].
  Configuration load() => _loadIncludeConfig()
      .merge(_loadGlobalTestConfig())
      .merge(_loadLocalTestConfig())
      .merge(_loadGlobalRunnerConfig())
      .merge(_loadLocalRunnerConfig());

  /// If an `include` node is contained in [node], merges and returns [config].
  Configuration _loadIncludeConfig() {
    if (!_runnerConfig) {
      _disallow('include');
      return Configuration.empty;
    }

    var includeNode = _document.nodes['include'];
    if (includeNode == null) return Configuration.empty;

    var includePath = _parseNode(includeNode, 'include path', p.fromUri);
    var basePath =
        p.join(p.dirname(p.fromUri(_document.span.sourceUrl)), includePath);
    try {
      return self.load(basePath);
    } on FileSystemException catch (error) {
      throw SourceSpanFormatException(
          getErrorMessage(error), includeNode.span, _source);
    }
  }

  /// Loads test configuration that's allowed in the global configuration file.
  Configuration _loadGlobalTestConfig() {
    var verboseTrace = _getBool('verbose_trace');
    var chainStackTraces = _getBool('chain_stack_traces');
    var foldStackFrames = _loadFoldedStackFrames();
    var jsTrace = _getBool('js_trace');

    var timeout = _parseValue('timeout', (value) => Timeout.parse(value));

    var onPlatform = _getMap('on_platform',
        key: (keyNode) => _parseNode(keyNode, 'on_platform key',
            (value) => PlatformSelector.parse(value, keyNode.span)),
        value: (valueNode) =>
            _nestedConfig(valueNode, 'on_platform value', runnerConfig: false));

    var onOS = _getMap('on_os',
        key: (keyNode) {
          _validate(keyNode, 'on_os key must be a string.',
              (value) => value is String);

          var os = OperatingSystem.find(keyNode.value as String);
          if (os != null) return os;

          throw SourceSpanFormatException(
              'Invalid on_os key: No such operating system.',
              keyNode.span,
              _source);
        },
        value: (valueNode) => _nestedConfig(valueNode, 'on_os value'));

    var presets = _getMap('presets',
        key: (keyNode) => _parseIdentifierLike(keyNode, 'presets key'),
        value: (valueNode) => _nestedConfig(valueNode, 'presets value'));

    var config = Configuration(
            verboseTrace: verboseTrace,
            jsTrace: jsTrace,
            timeout: timeout,
            presets: presets,
            chainStackTraces: chainStackTraces,
            foldTraceExcept: foldStackFrames['except'],
            foldTraceOnly: foldStackFrames['only'])
        .merge(_extractPresets<PlatformSelector>(
            onPlatform, (map) => Configuration(onPlatform: map)));

    var osConfig = onOS[currentOS];
    return osConfig == null ? config : config.merge(osConfig);
  }

  /// Loads test configuration that's not allowed in the global configuration
  /// file.
  ///
  /// If [_global] is `true`, this will error if there are any local test-level
  /// configuration fields.
  Configuration _loadLocalTestConfig() {
    if (_global) {
      _disallow('skip');
      _disallow('retry');
      _disallow('test_on');
      _disallow('add_tags');
      _disallow('tags');
      return Configuration.empty;
    }

    var skipRaw = _getValue('skip', 'boolean or string',
        (value) => value is bool || value is String);
    String skipReason;
    bool skip;
    if (skipRaw is String) {
      skipReason = skipRaw;
      skip = true;
    } else {
      skip = skipRaw as bool;
    }

    var testOn = _parsePlatformSelector('test_on');

    var addTags = _getList(
        'add_tags', (tagNode) => _parseIdentifierLike(tagNode, 'Tag name'));

    var tags = _getMap('tags',
        key: (keyNode) => _parseNode(
            keyNode, 'tags key', (value) => BooleanSelector.parse(value)),
        value: (valueNode) =>
            _nestedConfig(valueNode, 'tag value', runnerConfig: false));

    var retry = _getNonNegativeInt('retry');

    return Configuration(
            skip: skip,
            retry: retry,
            skipReason: skipReason,
            testOn: testOn,
            addTags: addTags)
        .merge(_extractPresets<BooleanSelector>(
            tags, (map) => Configuration(tags: map)));
  }

  /// Loads runner configuration that's allowed in the global configuration
  /// file.
  ///
  /// If [_runnerConfig] is `false`, this will error if there are any
  /// runner-level configuration fields.
  Configuration _loadGlobalRunnerConfig() {
    if (!_runnerConfig) {
      _disallow('pause_after_load');
      _disallow('reporter');
      _disallow('file_reporters');
      _disallow('concurrency');
      _disallow('names');
      _disallow('plain_names');
      _disallow('platforms');
      _disallow('add_presets');
      _disallow('override_platforms');
      _disallow('include');
      return Configuration.empty;
    }

    var pauseAfterLoad = _getBool('pause_after_load');
    var runSkipped = _getBool('run_skipped');

    var reporter = _getString('reporter');
    if (reporter != null && !allReporters.keys.contains(reporter)) {
      _error('Unknown reporter "$reporter".', 'reporter');
    }

    var fileReporters = _getMap('file_reporters', key: (keyNode) {
      _validate(keyNode, 'file_reporters key must be a string',
          (value) => value is String);
      final reporter = keyNode.value as String;
      if (!allReporters.keys.contains(reporter)) {
        _error('Unknown reporter "$reporter".', 'file_reporters');
      }
      return reporter;
    }, value: (valueNode) {
      _validate(valueNode, 'file_reporters value must be a string',
          (value) => value is String);
      return valueNode.value as String;
    });

    var concurrency = _getInt('concurrency');

    // The UI term "platform" corresponds with the implementation term
    // "runtime". The [Runtime] class used to be called [TestPlatform], but it
    // was changed to avoid conflicting with [SuitePlatform]. We decided not to
    // also change the UI to avoid a painful migration.
    var runtimes = _getList(
        'platforms',
        (runtimeNode) => RuntimeSelection(
            _parseIdentifierLike(runtimeNode, 'Platform name'),
            runtimeNode.span));

    var chosenPresets = _getList('add_presets',
        (presetNode) => _parseIdentifierLike(presetNode, 'Preset name'));

    var overrideRuntimes = _loadOverrideRuntimes();

    var customHtmlTemplatePath = _getString('custom_html_template_path');

    return Configuration(
        pauseAfterLoad: pauseAfterLoad,
        customHtmlTemplatePath: customHtmlTemplatePath,
        runSkipped: runSkipped,
        reporter: reporter,
        fileReporters: fileReporters,
        concurrency: concurrency,
        runtimes: runtimes,
        chosenPresets: chosenPresets,
        overrideRuntimes: overrideRuntimes);
  }

  /// Loads the `override_platforms` field.
  Map<String, RuntimeSettings> _loadOverrideRuntimes() {
    var runtimesNode =
        _getNode('override_platforms', 'map', (value) => value is Map)
            as YamlMap;
    if (runtimesNode == null) return const {};

    var runtimes = <String, RuntimeSettings>{};
    runtimesNode.nodes.forEach((identifierNode, valueNode) {
      var identifier = _parseIdentifierLike(
          identifierNode as YamlNode, 'Platform identifier');

      _validate(valueNode, 'Platform definition must be a map.',
          (value) => value is Map);
      var map = valueNode as YamlMap;

      var settings = _expect(map, 'settings');
      _validate(settings, 'Must be a map.', (value) => value is Map);

      runtimes[identifier] = RuntimeSettings(
          identifier, (identifierNode as YamlNode).span, [settings as YamlMap]);
    });
    return runtimes;
  }

  /// Loads runner configuration that's not allowed in the global configuration
  /// file.
  ///
  /// If [_runnerConfig] is `false` or if [_global] is `true`, this will error
  /// if there are any local test-level configuration fields.
  Configuration _loadLocalRunnerConfig() {
    if (!_runnerConfig || _global) {
      _disallow('pub_serve');
      _disallow('names');
      _disallow('plain_names');
      _disallow('paths');
      _disallow('filename');
      _disallow('include_tags');
      _disallow('exclude_tags');
      _disallow('define_platforms');
      return Configuration.empty;
    }

    var pubServePort = _getInt('pub_serve');

    var patterns = _getList('names', (nameNode) {
      _validate(nameNode, 'Names must be strings.', (value) => value is String);
      return _parseNode(nameNode, 'name', (value) => RegExp(value));
    })
      ..addAll(_getList('plain_names', (nameNode) {
        _validate(
            nameNode, 'Names must be strings.', (value) => value is String);
        return _parseNode(nameNode, 'name', (value) => RegExp(value));
      }));

    var paths = _getList('paths', (pathNode) {
      _validate(pathNode, 'Paths must be strings.', (value) => value is String);
      _validate(pathNode, 'Paths must be relative.',
          (value) => p.url.isRelative(value as String));

      return _parseNode(pathNode, 'path', p.fromUri);
    });

    var filename = _parseValue('filename', (value) => Glob(value));

    var includeTags = _parseBooleanSelector('include_tags');
    var excludeTags = _parseBooleanSelector('exclude_tags');

    var defineRuntimes = _loadDefineRuntimes();

    return Configuration(
        pubServePort: pubServePort,
        patterns: patterns,
        paths: paths,
        filename: filename,
        includeTags: includeTags,
        excludeTags: excludeTags,
        defineRuntimes: defineRuntimes);
  }

  /// Returns a map representation of the `fold_stack_frames` configuration.
  ///
  /// The key `except` will correspond to the list of packages to fold.
  /// The key `only` will correspond to the list of packages to keep in a
  /// test [Chain].
  Map<String, List<String>> _loadFoldedStackFrames() {
    var foldOptionSet = false;
    return _getMap('fold_stack_frames', key: (keyNode) {
      _validate(keyNode, 'Must be a string', (value) => value is String);
      _validate(keyNode, 'Must be "only" or "except".',
          (value) => value == 'only' || value == 'except');

      if (foldOptionSet) {
        throw SourceSpanFormatException(
            'Can only contain one of "only" or "except".',
            keyNode.span,
            _source);
      }
      foldOptionSet = true;
      return keyNode.value as String;
    }, value: (valueNode) {
      _validate(
          valueNode,
          'Folded packages must be strings.',
          (valueList) =>
              valueList is YamlList &&
              valueList.every((value) => value is String));

      _validate(
          valueNode,
          'Invalid package name.',
          (valueList) => (valueList as Iterable)
              .every((value) => _packageName.hasMatch(value as String)));

      return List<String>.from(valueNode.value as Iterable);
    });
  }

  /// Loads the `define_platforms` field.
  Map<String, CustomRuntime> _loadDefineRuntimes() {
    var runtimesNode =
        _getNode('define_platforms', 'map', (value) => value is Map) as YamlMap;
    if (runtimesNode == null) return const {};

    var runtimes = <String, CustomRuntime>{};
    runtimesNode.nodes.forEach((identifierNode, valueNode) {
      var identifier = _parseIdentifierLike(
          identifierNode as YamlNode, 'Platform identifier');

      _validate(valueNode, 'Platform definition must be a map.',
          (value) => value is Map);
      var map = valueNode as YamlMap;

      var nameNode = _expect(map, 'name');
      _validate(nameNode, 'Must be a string.', (value) => value is String);
      var name = nameNode.value as String;

      var parentNode = _expect(map, 'extends');
      var parent = _parseIdentifierLike(parentNode, 'Platform parent');

      var settings = _expect(map, 'settings');
      _validate(settings, 'Must be a map.', (value) => value is Map);

      runtimes[identifier] = CustomRuntime(
          name,
          nameNode.span,
          identifier,
          (identifierNode as YamlNode).span,
          parent,
          parentNode.span,
          settings as YamlMap);
    });
    return runtimes;
  }

  /// Throws an exception with [message] if [test] returns `false` when passed
  /// [node]'s value.
  void _validate(YamlNode node, String message, bool Function(dynamic) test) {
    if (test(node.value)) return;
    throw SourceSpanFormatException(message, node.span, _source);
  }

  /// Returns the value of the node at [field].
  ///
  /// If [typeTest] returns `false` for that value, instead throws an error
  /// complaining that the field is not a [typeName].
  dynamic _getValue(
      String field, String typeName, bool Function(dynamic) typeTest) {
    var value = _document[field];
    if (value == null || typeTest(value)) return value;
    _error('$field must be ${a(typeName)}.', field);
  }

  /// Returns the YAML node at [field].
  ///
  /// If [typeTest] returns `false` for that node's value, instead throws an
  /// error complaining that the field is not a [typeName].
  YamlNode _getNode(
      String field, String typeName, bool Function(dynamic) typeTest) {
    var node = _document.nodes[field];
    if (node == null) return null;
    _validate(node, '$field must be ${a(typeName)}.', typeTest);
    return node;
  }

  /// Asserts that [field] is an int and returns its value.
  int _getInt(String field) =>
      _getValue(field, 'int', (value) => value is int) as int;

  /// Asserts that [field] is a non-negative int and returns its value.
  int _getNonNegativeInt(String field) => _getValue(
      field, 'non-negative int', (value) => value is int && value >= 0) as int;

  /// Asserts that [field] is a boolean and returns its value.
  bool _getBool(String field) =>
      _getValue(field, 'boolean', (value) => value is bool) as bool;

  /// Asserts that [field] is a string and returns its value.
  String _getString(String field) =>
      _getValue(field, 'string', (value) => value is String) as String;

  /// Asserts that [field] is a list and runs [forElement] for each element it
  /// contains.
  ///
  /// Returns a list of values returned by [forElement].
  List<T> _getList<T>(String field, T Function(YamlNode) forElement) {
    var node = _getNode(field, 'list', (value) => value is List) as YamlList;
    if (node == null) return [];
    return node.nodes.map(forElement).toList();
  }

  /// Asserts that [field] is a map and runs [key] and [value] for each pair.
  ///
  /// Returns a map with the keys and values returned by [key] and [value]. Each
  /// of these defaults to asserting that the value is a string.
  Map<K, V> _getMap<K, V>(String field,
      {K Function(YamlNode) key, V Function(YamlNode) value}) {
    var node = _getNode(field, 'map', (value) => value is Map) as YamlMap;
    if (node == null) return {};

    key ??= (keyNode) {
      _validate(
          keyNode, '$field keys must be strings.', (value) => value is String);

      return keyNode.value as K;
    };

    value ??= (valueNode) {
      _validate(valueNode, '$field values must be strings.',
          (value) => value is String);

      return valueNode.value as V;
    };

    return node.nodes.map((keyNode, valueNode) =>
        MapEntry(key(keyNode as YamlNode), value(valueNode)));
  }

  /// Verifies that [node]'s value is an optionally hyphenated Dart identifier,
  /// and returns it
  String _parseIdentifierLike(YamlNode node, String name) {
    _validate(node, '$name must be a string.', (value) => value is String);
    _validate(node, '$name must be an (optionally hyphenated) Dart identifier.',
        (value) => (value as String).contains(anchoredHyphenatedIdentifier));
    return node.value as String;
  }

  /// Parses [node]'s value as a boolean selector.
  BooleanSelector _parseBooleanSelector(String name) =>
      _parseValue(name, (value) => BooleanSelector.parse(value));

  /// Parses [node]'s value as a platform selector.
  PlatformSelector _parsePlatformSelector(String field) {
    var node = _document.nodes[field];
    if (node == null) return null;
    return _parseNode(
        node, field, (value) => PlatformSelector.parse(value, node.span));
  }

  /// Asserts that [node] is a string, passes its value to [parse], and returns
  /// the result.
  ///
  /// If [parse] throws a [FormatException], it's wrapped to include [node]'s
  /// span.
  T _parseNode<T>(YamlNode node, String name, T Function(String) parse) {
    _validate(node, '$name must be a string.', (value) => value is String);

    try {
      return parse(node.value as String);
    } on FormatException catch (error) {
      throw SourceSpanFormatException(
          'Invalid $name: ${error.message}', node.span, _source);
    }
  }

  /// Asserts that [field] is a string, passes it to [parse], and returns the
  /// result.
  ///
  /// If [parse] throws a [FormatException], it's wrapped to include [field]'s
  /// span.
  T _parseValue<T>(String field, T Function(String) parse) {
    var node = _document.nodes[field];
    if (node == null) return null;
    return _parseNode(node, field, parse);
  }

  /// Parses a nested configuration document.
  ///
  /// [name] is the name of the field, which is used for error-handling.
  /// [runnerConfig] controls whether runner configuration is allowed in the
  /// nested configuration. It defaults to [_runnerConfig].
  Configuration _nestedConfig(YamlNode node, String name, {bool runnerConfig}) {
    if (node == null || node.value == null) return Configuration.empty;

    _validate(node, '$name must be a map.', (value) => value is Map);
    var loader = _ConfigurationLoader(node as YamlMap, _source,
        global: _global, runnerConfig: runnerConfig ?? _runnerConfig);
    return loader.load();
  }

  /// Takes a map that contains [Configuration]s and extracts any
  /// preset-specific configuration into a parent [Configuration].
  ///
  /// This is needed because parameters to [new Configuration] such as
  /// `onPlatform` take maps to [SuiteConfiguration]s. [SuiteConfiguration]
  /// doesn't support preset-specific configuration, so this extracts the preset
  /// logic into a parent [Configuration], leaving only maps to
  /// [SuiteConfiguration]s. The [create] function is used to construct
  /// [Configuration]s from the resolved maps.
  Configuration _extractPresets<T>(Map<T, Configuration> map,
      Configuration Function(Map<T, SuiteConfiguration>) create) {
    if (map.isEmpty) return Configuration.empty;

    var base = <T, SuiteConfiguration>{};
    var presets = <String, Map<T, SuiteConfiguration>>{};
    map.forEach((key, config) {
      base[key] = config.suiteDefaults;
      config.presets.forEach((preset, presetConfig) {
        presets.putIfAbsent(preset, () => {})[key] = presetConfig.suiteDefaults;
      });
    });

    if (presets.isEmpty) {
      return base.isEmpty ? Configuration.empty : create(base);
    } else {
      var newPresets = presets.map((key, map) => MapEntry(key, create(map)));
      return create(base).change(presets: newPresets);
    }
  }

  /// Asserts that [map] has a field named [field] and returns it.
  YamlNode _expect(YamlMap map, String field) {
    var node = map.nodes[field];
    if (node != null) return node;

    throw SourceSpanFormatException(
        'Missing required field "$field".', map.span, _source);
  }

  /// Throws an error if a field named [field] exists at this level.
  void _disallow(String field) {
    if (!_document.containsKey(field)) return;

    throw SourceSpanFormatException(
        "$field isn't supported here.",
        // We need the key as a [YamlNode] to get its span.
        (_document.nodes.keys.firstWhere((key) => key.value == field)
                as YamlNode)
            .span,
        _source);
  }

  /// Throws a [SourceSpanFormatException] with [message] about [field].
  void _error(String message, String field) {
    throw SourceSpanFormatException(
        message, _document.nodes[field].span, _source);
  }
}
