// Copyright (c) 2014, 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:source_span/source_span.dart';

import 'style.dart';
import 'yaml_document.dart';

/// An event emitted by a [Parser].
class Event {
  /// The event type.
  final EventType type;

  /// The span associated with the event.
  final FileSpan span;

  Event(this.type, this.span);

  String toString() => type.toString();
}

/// An event indicating the beginning of a YAML document.
class DocumentStartEvent implements Event {
  get type => EventType.DOCUMENT_START;
  final FileSpan span;

  /// The document's `%YAML` directive, or `null` if there was none.
  final VersionDirective versionDirective;

  /// The document's `%TAG` directives, if any.
  final List<TagDirective> tagDirectives;

  /// Whether the document started implicitly (that is, without an explicit
  /// `===` sequence).
  final bool isImplicit;

  DocumentStartEvent(this.span, {this.versionDirective,
          List<TagDirective> tagDirectives, this.isImplicit: true})
      : tagDirectives = tagDirectives == null ? [] : tagDirectives;

  String toString() => "DOCUMENT_START";
}

/// An event indicating the end of a YAML document.
class DocumentEndEvent implements Event {
  get type => EventType.DOCUMENT_END;
  final FileSpan span;

  /// Whether the document ended implicitly (that is, without an explicit
  /// `...` sequence).
  final bool isImplicit;

  DocumentEndEvent(this.span, {this.isImplicit: true});

  String toString() => "DOCUMENT_END";
}

/// An event indicating that an alias was referenced.
class AliasEvent implements Event {
  get type => EventType.ALIAS;
  final FileSpan span;

  /// The name of the anchor.
  final String name;

  AliasEvent(this.span, this.name);

  String toString() => "ALIAS $name";
}

/// A base class for events that can have anchor and tag properties associated
/// with them.
abstract class _ValueEvent implements Event {
  /// The name of the value's anchor, or `null` if it wasn't anchored.
  String get anchor;

  /// The text of the value's tag, or `null` if it wasn't tagged.
  String get tag;

  String toString() {
    var buffer = new StringBuffer('$type');
    if (anchor != null) buffer.write(" &$anchor");
    if (tag != null) buffer.write(" $tag");
    return buffer.toString();
  }
}

/// An event indicating a single scalar value.
class ScalarEvent extends _ValueEvent {
  get type => EventType.SCALAR;
  final FileSpan span;
  final String anchor;
  final String tag;

  /// The contents of the scalar.
  final String value;

  /// The style of the scalar in the original source.
  final ScalarStyle style;

  ScalarEvent(this.span, this.value, this.style, {this.anchor, this.tag});

  String toString() => "${super.toString()} \"$value\"";
}

/// An event indicating the beginning of a sequence.
class SequenceStartEvent extends _ValueEvent {
  get type => EventType.SEQUENCE_START;
  final FileSpan span;
  final String anchor;
  final String tag;

  /// The style of the collection in the original source.
  final CollectionStyle style;

  SequenceStartEvent(this.span, this.style, {this.anchor, this.tag});
}

/// An event indicating the beginning of a mapping.
class MappingStartEvent extends _ValueEvent {
  get type => EventType.MAPPING_START;
  final FileSpan span;
  final String anchor;
  final String tag;

  /// The style of the collection in the original source.
  final CollectionStyle style;

  MappingStartEvent(this.span, this.style, {this.anchor, this.tag});
}

/// An enum of types of [Event] object.
class EventType {
  static const STREAM_START = const EventType._("STREAM_START");
  static const STREAM_END = const EventType._("STREAM_END");

  static const DOCUMENT_START = const EventType._("DOCUMENT_START");
  static const DOCUMENT_END = const EventType._("DOCUMENT_END");

  static const ALIAS = const EventType._("ALIAS");
  static const SCALAR = const EventType._("SCALAR");

  static const SEQUENCE_START = const EventType._("SEQUENCE_START");
  static const SEQUENCE_END = const EventType._("SEQUENCE_END");

  static const MAPPING_START = const EventType._("MAPPING_START");
  static const MAPPING_END = const EventType._("MAPPING_END");

  final String name;

  const EventType._(this.name);

  String toString() => name;
}
