// Copyright (c) 2014, the Dart project authors.
// Copyright (c) 2006, Kirill Simonov.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'package:source_span/source_span.dart';

import 'charcodes.dart';
import 'equality.dart';
import 'error_listener.dart';
import 'event.dart';
import 'parser.dart';
import 'yaml_document.dart';
import 'yaml_exception.dart';
import 'yaml_node.dart';

/// A loader that reads [Event]s emitted by a [Parser] and emits
/// [YamlDocument]s.
///
/// This is based on the libyaml loader, available at
/// https://github.com/yaml/libyaml/blob/master/src/loader.c. The license for
/// that is available in ../../libyaml-license.txt.
class Loader {
  /// The underlying [Parser] that generates [Event]s.
  final Parser _parser;

  /// Aliases by the alias name.
  final _aliases = <String, YamlNode>{};

  /// Anchors that are currently being resolved.
  final _activeAnchors = <String>{};

  /// The span of the entire stream emitted so far.
  FileSpan get span => _span;
  FileSpan _span;

  /// Creates a loader that loads [source].
  factory Loader(String source,
      {Uri? sourceUrl, bool recover = false, ErrorListener? errorListener}) {
    var parser = Parser(source,
        sourceUrl: sourceUrl, recover: recover, errorListener: errorListener);
    var event = parser.parse();
    assert(event.type == EventType.streamStart);
    return Loader._(parser, event.span);
  }

  Loader._(this._parser, this._span);

  /// Loads the next document from the stream.
  ///
  /// If there are no more documents, returns `null`.
  YamlDocument? load() {
    if (_parser.isDone) return null;

    var event = _parser.parse();
    if (event.type == EventType.streamEnd) {
      _span = _span.expand(event.span);
      return null;
    }

    var document = _loadDocument(event as DocumentStartEvent);
    _span = _span.expand(document.span as FileSpan);
    _aliases.clear();
    return document;
  }

  /// Composes a document object.
  YamlDocument _loadDocument(DocumentStartEvent firstEvent) {
    var contents = _loadNode(_parser.parse());

    var lastEvent = _parser.parse() as DocumentEndEvent;
    assert(lastEvent.type == EventType.documentEnd);

    return YamlDocument.internal(
        contents,
        firstEvent.span.expand(lastEvent.span),
        firstEvent.versionDirective,
        firstEvent.tagDirectives,
        startImplicit: firstEvent.isImplicit,
        endImplicit: lastEvent.isImplicit);
  }

  /// Composes a node.
  YamlNode _loadNode(Event firstEvent) => switch (firstEvent.type) {
        EventType.alias => _loadAlias(firstEvent as AliasEvent),
        EventType.scalar => _loadScalar(firstEvent as ScalarEvent),
        EventType.sequenceStart =>
          _loadSequence(firstEvent as SequenceStartEvent),
        EventType.mappingStart => _loadMapping(firstEvent as MappingStartEvent),
        _ => throw StateError('Unreachable')
      };

  /// Registers an anchor.
  void _registerAnchor(String? anchor, YamlNode node) {
    if (anchor == null) return;

    // libyaml throws an error for duplicate anchors, but example 7.1 makes it
    // clear that they should be overridden:
    // http://yaml.org/spec/1.2/spec.html#id2786448.

    _aliases[anchor] = node;
  }

  /// Composes a node corresponding to an alias.
  YamlNode _loadAlias(AliasEvent event) {
    var alias = _aliases[event.name];
    if (alias != null) {
      if (_activeAnchors.contains(event.name)) {
        throw YamlException(
            'Self-referential collections are not supported.', event.span);
      }
      return alias;
    }

    throw YamlException('Undefined alias.', event.span);
  }

  /// Composes a scalar node.
  YamlNode _loadScalar(ScalarEvent scalar) {
    YamlNode node;
    if (scalar.tag == '!') {
      node = YamlScalar.internal(scalar.value, scalar);
    } else if (scalar.tag != null) {
      node = _parseByTag(scalar);
    } else {
      node = _parseScalar(scalar);
    }

    _registerAnchor(scalar.anchor, node);
    return node;
  }

  /// Composes a sequence node.
  YamlNode _loadSequence(SequenceStartEvent firstEvent) {
    if (firstEvent.tag != '!' &&
        firstEvent.tag != null &&
        firstEvent.tag != 'tag:yaml.org,2002:seq') {
      throw YamlException('Invalid tag for sequence.', firstEvent.span);
    }

    var children = <YamlNode>[];
    var node = YamlList.internal(children, firstEvent.span, firstEvent.style);
    _registerAnchor(firstEvent.anchor, node);

    Event event;
    try {
      if (firstEvent.anchor case final anchor?) _activeAnchors.add(anchor);
      event = _parser.parse();
      while (event.type != EventType.sequenceEnd) {
        children.add(_loadNode(event));
        event = _parser.parse();
      }
    } finally {
      if (firstEvent.anchor case final anchor?) _activeAnchors.remove(anchor);
    }

    setSpan(node, firstEvent.span.expand(event.span));
    return node;
  }

  /// Composes a mapping node.
  YamlNode _loadMapping(MappingStartEvent firstEvent) {
    if (firstEvent.tag != '!' &&
        firstEvent.tag != null &&
        firstEvent.tag != 'tag:yaml.org,2002:map') {
      throw YamlException('Invalid tag for mapping.', firstEvent.span);
    }

    var children = deepEqualsMap<dynamic, YamlNode>();
    var node = YamlMap.internal(children, firstEvent.span, firstEvent.style);
    _registerAnchor(firstEvent.anchor, node);

    Event event;
    try {
      if (firstEvent.anchor case final anchor?) _activeAnchors.add(anchor);
      event = _parser.parse();
      while (event.type != EventType.mappingEnd) {
        var key = _loadNode(event);
        var value = _loadNode(_parser.parse());
        if (children.containsKey(key)) {
          throw YamlException('Duplicate mapping key.', key.span);
        }

        children[key] = value;
        event = _parser.parse();
      }
    } finally {
      if (firstEvent.anchor case final anchor?) _activeAnchors.remove(anchor);
    }

    setSpan(node, firstEvent.span.expand(event.span));
    return node;
  }

  /// Parses a scalar according to its tag name.
  YamlScalar _parseByTag(ScalarEvent scalar) {
    switch (scalar.tag) {
      case 'tag:yaml.org,2002:null':
        var result = _parseNull(scalar);
        if (result != null) return result;
        throw YamlException('Invalid null scalar.', scalar.span);
      case 'tag:yaml.org,2002:bool':
        var result = _parseBool(scalar);
        if (result != null) return result;
        throw YamlException('Invalid bool scalar.', scalar.span);
      case 'tag:yaml.org,2002:int':
        var result = _parseNumber(scalar, allowFloat: false);
        if (result != null) return result;
        throw YamlException('Invalid int scalar.', scalar.span);
      case 'tag:yaml.org,2002:float':
        var result = _parseNumber(scalar, allowInt: false);
        if (result != null) return result;
        throw YamlException('Invalid float scalar.', scalar.span);
      case 'tag:yaml.org,2002:str':
        return YamlScalar.internal(scalar.value, scalar);
      default:
        throw YamlException('Undefined tag: ${scalar.tag}.', scalar.span);
    }
  }

  /// Parses [scalar], which may be one of several types.
  YamlScalar _parseScalar(ScalarEvent scalar) =>
      _tryParseScalar(scalar) ?? YamlScalar.internal(scalar.value, scalar);

  /// Tries to parse [scalar].
  ///
  /// If parsing fails, this returns `null`, indicating that the scalar should
  /// be parsed as a string.
  YamlScalar? _tryParseScalar(ScalarEvent scalar) {
    // Quickly check for the empty string, which means null.
    var length = scalar.value.length;
    if (length == 0) return YamlScalar.internal(null, scalar);

    // Dispatch on the first character.
    var firstChar = scalar.value.codeUnitAt(0);
    return switch (firstChar) {
      $dot || $plus || $minus => _parseNumber(scalar),
      $n || $N => length == 4 ? _parseNull(scalar) : null,
      $t || $T => length == 4 ? _parseBool(scalar) : null,
      $f || $F => length == 5 ? _parseBool(scalar) : null,
      $tilde => length == 1 ? YamlScalar.internal(null, scalar) : null,
      _ => (firstChar >= $0 && firstChar <= $9) ? _parseNumber(scalar) : null
    };
  }

  /// Parse a null scalar.
  ///
  /// Returns a Dart `null` if parsing fails.
  YamlScalar? _parseNull(ScalarEvent scalar) => switch (scalar.value) {
        '' ||
        'null' ||
        'Null' ||
        'NULL' ||
        '~' =>
          YamlScalar.internal(null, scalar),
        _ => null
      };

  /// Parse a boolean scalar.
  ///
  /// Returns `null` if parsing fails.
  YamlScalar? _parseBool(ScalarEvent scalar) => switch (scalar.value) {
        'true' || 'True' || 'TRUE' => YamlScalar.internal(true, scalar),
        'false' || 'False' || 'FALSE' => YamlScalar.internal(false, scalar),
        _ => null
      };

  /// Parses a numeric scalar.
  ///
  /// Returns `null` if parsing fails.
  YamlScalar? _parseNumber(ScalarEvent scalar,
      {bool allowInt = true, bool allowFloat = true}) {
    var value = _parseNumberValue(scalar.value,
        allowInt: allowInt, allowFloat: allowFloat);
    return value == null ? null : YamlScalar.internal(value, scalar);
  }

  /// Parses the value of a number.
  ///
  /// Returns the number if it's parsed successfully, or `null` if it's not.
  num? _parseNumberValue(String contents,
      {bool allowInt = true, bool allowFloat = true}) {
    assert(allowInt || allowFloat);

    var firstChar = contents.codeUnitAt(0);
    var length = contents.length;

    // Quick check for single digit integers.
    if (allowInt && length == 1) {
      var value = firstChar - $0;
      return value >= 0 && value <= 9 ? value : null;
    }

    var secondChar = contents.codeUnitAt(1);

    // Hexadecimal or octal integers.
    if (allowInt && firstChar == $0) {
      // int.tryParse supports 0x natively.
      if (secondChar == $x) return int.tryParse(contents);

      if (secondChar == $o) {
        var afterRadix = contents.substring(2);
        return int.tryParse(afterRadix, radix: 8);
      }
    }

    // Int or float starting with a digit or a +/- sign.
    if ((firstChar >= $0 && firstChar <= $9) ||
        ((firstChar == $plus || firstChar == $minus) &&
            secondChar >= $0 &&
            secondChar <= $9)) {
      // Try to parse an int or, failing that, a double.
      num? result;
      if (allowInt) {
        // Pass "radix: 10" explicitly to ensure that "-0x10", which is valid
        // Dart but invalid YAML, doesn't get parsed.
        result = int.tryParse(contents, radix: 10);
      }

      if (allowFloat) result ??= double.tryParse(contents);
      return result;
    }

    if (!allowFloat) return null;

    // Now the only possibility is to parse a float starting with a dot or a
    // sign and a dot, or the signed/unsigned infinity values and not-a-numbers.
    if ((firstChar == $dot && secondChar >= $0 && secondChar <= $9) ||
        (firstChar == $minus || firstChar == $plus) && secondChar == $dot) {
      // Starting with a . and a number or a sign followed by a dot.
      if (length == 5) {
        switch (contents) {
          case '+.inf':
          case '+.Inf':
          case '+.INF':
            return double.infinity;
          case '-.inf':
          case '-.Inf':
          case '-.INF':
            return -double.infinity;
        }
      }

      return double.tryParse(contents);
    }

    if (length == 4 && firstChar == $dot) {
      switch (contents) {
        case '.inf':
        case '.Inf':
        case '.INF':
          return double.infinity;
        case '.nan':
        case '.NaN':
        case '.NAN':
          return double.nan;
      }
    }

    return null;
  }
}
