// 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 'annotated_code_helper.dart';

enum IdKind {
  /// Id used for top level or class members. This is used in [MemberId].
  member,

  /// Id used for classes. This is used in [ClassId].
  cls,

  /// Id used for libraries. This is used in [LibraryId].
  library,

  /// Id used for a code point at certain offset. The id represents the default
  /// use of the code point, often a read access. This is used in [NodeId].
  node,

  /// Id used for an invocation at certain offset. This is used in [NodeId].
  invoke,

  /// Id used for an assignment at certain offset. This is used in [NodeId].
  update,

  /// Id used for the iterator expression of a for-in at certain offset. This is
  /// used in [NodeId].
  iterator,

  /// Id used for the implicit call to `Iterator.current` in a for-in at certain
  /// offset. This is used in [NodeId].
  current,

  /// Id used for the implicit call to `Iterator.moveNext` in a for-in at
  /// certain offset. This is used in [NodeId].
  moveNext,

  /// Id used for the implicit as expression inserted by the compiler.
  implicitAs,

  /// Id used for the statement at certain offset. This is used in [NodeId].
  stmt,

  /// Id used for the error reported at certain offset. This is used in
  /// [NodeId].
  error,
}

/// Id for a code point or element.
abstract class Id {
  IdKind get kind;

  /// Indicates whether the id refers to an element defined outside of the test
  /// case itself (e.g. some tests may need to refer to properties of elements
  /// in `dart:core`).
  bool get isGlobal;

  /// Display name for this id.
  String get descriptor;
}

class IdValue {
  final Id id;
  final Annotation annotation;
  final String value;

  const IdValue(this.id, this.annotation, this.value);

  @override
  int get hashCode => id.hashCode * 13 + value.hashCode * 17;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! IdValue) return false;
    return id == other.id && value == other.value;
  }

  @override
  String toString() => idToString(id, value);

  static String idToString(Id id, String value) {
    switch (id.kind) {
      case IdKind.member:
        MemberId elementId = id as MemberId;
        return '$memberPrefix${elementId.name}:$value';
      case IdKind.cls:
        ClassId classId = id as ClassId;
        return '$classPrefix${classId.name}:$value';
      case IdKind.library:
        return '$libraryPrefix$value';
      case IdKind.node:
        return value;
      case IdKind.invoke:
        return '$invokePrefix$value';
      case IdKind.update:
        return '$updatePrefix$value';
      case IdKind.iterator:
        return '$iteratorPrefix$value';
      case IdKind.current:
        return '$currentPrefix$value';
      case IdKind.moveNext:
        return '$moveNextPrefix$value';
      case IdKind.implicitAs:
        return '$implicitAsPrefix$value';
      case IdKind.stmt:
        return '$stmtPrefix$value';
      case IdKind.error:
        return '$errorPrefix$value';
    }
  }

  static const String globalPrefix = "global#";
  static const String memberPrefix = "member: ";
  static const String classPrefix = "class: ";
  static const String libraryPrefix = "library: ";
  static const String invokePrefix = "invoke: ";
  static const String updatePrefix = "update: ";
  static const String iteratorPrefix = "iterator: ";
  static const String currentPrefix = "current: ";
  static const String moveNextPrefix = "moveNext: ";
  static const String implicitAsPrefix = "as: ";
  static const String stmtPrefix = "stmt: ";
  static const String errorPrefix = "error: ";

  static IdValue decode(Uri sourceUri, Annotation annotation, String text,
      {bool preserveWhitespaceInAnnotations: false,
      bool preserveInfixWhitespace: false}) {
    int offset = annotation.offset;
    Id id;
    String expected;
    if (text.startsWith(memberPrefix)) {
      text = text.substring(memberPrefix.length);
      int colonPos = text.indexOf(':');
      if (colonPos == -1) throw "Invalid member id: '$text'";
      String name = text.substring(0, colonPos);
      bool isGlobal = name.startsWith(globalPrefix);
      if (isGlobal) {
        name = name.substring(globalPrefix.length);
      }
      id = new MemberId(name, isGlobal: isGlobal);
      expected = text.substring(colonPos + 1);
    } else if (text.startsWith(classPrefix)) {
      text = text.substring(classPrefix.length);
      int colonPos = text.indexOf(':');
      if (colonPos == -1) throw "Invalid class id: '$text'";
      String name = text.substring(0, colonPos);
      bool isGlobal = name.startsWith(globalPrefix);
      if (isGlobal) {
        name = name.substring(globalPrefix.length);
      }
      id = new ClassId(name, isGlobal: isGlobal);
      expected = text.substring(colonPos + 1);
    } else if (text.startsWith(libraryPrefix)) {
      id = new LibraryId(sourceUri);
      expected = text.substring(libraryPrefix.length);
    } else if (text.startsWith(invokePrefix)) {
      id = new NodeId(offset, IdKind.invoke);
      expected = text.substring(invokePrefix.length);
    } else if (text.startsWith(updatePrefix)) {
      id = new NodeId(offset, IdKind.update);
      expected = text.substring(updatePrefix.length);
    } else if (text.startsWith(iteratorPrefix)) {
      id = new NodeId(offset, IdKind.iterator);
      expected = text.substring(iteratorPrefix.length);
    } else if (text.startsWith(currentPrefix)) {
      id = new NodeId(offset, IdKind.current);
      expected = text.substring(currentPrefix.length);
    } else if (text.startsWith(moveNextPrefix)) {
      id = new NodeId(offset, IdKind.moveNext);
      expected = text.substring(moveNextPrefix.length);
    } else if (text.startsWith(implicitAsPrefix)) {
      id = new NodeId(offset, IdKind.implicitAs);
      expected = text.substring(implicitAsPrefix.length);
    } else if (text.startsWith(stmtPrefix)) {
      id = new NodeId(offset, IdKind.stmt);
      expected = text.substring(stmtPrefix.length);
    } else if (text.startsWith(errorPrefix)) {
      id = new NodeId(offset, IdKind.error);
      expected = text.substring(errorPrefix.length);
    } else {
      id = new NodeId(offset, IdKind.node);
      expected = text;
    }
    if (preserveWhitespaceInAnnotations) {
      // Keep all whitespace.
    } else if (preserveInfixWhitespace) {
      // Remove heading and trailing whitespace.
      expected = expected.trim();
    } else {
      // Remove unneeded whitespace.
      expected = expected.replaceAll(new RegExp(r'\s*(\n\s*)+\s*'), '');
    }
    return new IdValue(id, annotation, expected);
  }
}

/// Id for an member element.
class MemberId implements Id {
  final String? className;
  final String memberName;
  @override
  final bool isGlobal;

  factory MemberId(String text, {bool isGlobal: false}) {
    int dotPos = text.indexOf('.');
    if (dotPos != -1) {
      return new MemberId.internal(text.substring(dotPos + 1),
          className: text.substring(0, dotPos), isGlobal: isGlobal);
    } else {
      return new MemberId.internal(text, isGlobal: isGlobal);
    }
  }

  MemberId.internal(this.memberName, {this.className, this.isGlobal: false});

  @override
  int get hashCode => className.hashCode * 13 + memberName.hashCode * 17;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! MemberId) return false;
    return className == other.className && memberName == other.memberName;
  }

  @override
  IdKind get kind => IdKind.member;

  String get name => className != null ? '$className.$memberName' : memberName;

  @override
  String get descriptor => 'member $name';

  @override
  String toString() => 'member:$name';
}

/// Id for a class.
class ClassId implements Id {
  final String className;
  @override
  final bool isGlobal;

  ClassId(this.className, {this.isGlobal: false});

  @override
  int get hashCode => className.hashCode * 13;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! ClassId) return false;
    return className == other.className;
  }

  @override
  IdKind get kind => IdKind.cls;

  String get name => className;

  @override
  String get descriptor => 'class $name';

  @override
  String toString() => 'class:$name';
}

/// Id for a library.
class LibraryId implements Id {
  final Uri uri;

  LibraryId(this.uri);

  // TODO(johnniwinther): Support global library annotations.
  @override
  bool get isGlobal => false;

  @override
  int get hashCode => uri.hashCode * 13;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! LibraryId) return false;
    return uri == other.uri;
  }

  @override
  IdKind get kind => IdKind.library;

  String get name => uri.toString();

  @override
  String get descriptor => 'library $name';

  @override
  String toString() => 'library:$name';
}

/// Id for a code point defined by a kind and a code offset.
class NodeId implements Id {
  final int value;
  @override
  final IdKind kind;

  const NodeId(this.value, this.kind)
      :
        // ignore: unnecessary_null_comparison
        assert(value != null),
        assert(value >= 0);

  @override
  bool get isGlobal => false;

  @override
  int get hashCode => value.hashCode * 13 + kind.hashCode * 17;

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    if (other is! NodeId) return false;
    return value == other.value && kind == other.kind;
  }

  @override
  String get descriptor => 'offset $value ($kind)';

  @override
  String toString() => '$kind:$value';
}

class ActualData<T> {
  final Id id;
  final T value;
  final Uri uri;
  final int _offset;
  final Object object;

  ActualData(this.id, this.value, this.uri, this._offset, this.object);

  int get offset {
    if (id is NodeId) {
      NodeId nodeId = id as NodeId;
      return nodeId.value;
    } else {
      return _offset;
    }
  }

  String get objectText {
    return 'object `${'$object'.replaceAll('\n', '')}` (${object.runtimeType})';
  }

  @override
  String toString() => 'ActualData(id=$id,value=$value,uri=$uri,'
      'offset=$offset,object=$objectText)';
}

abstract class DataRegistry<T> {
  Map<Id, ActualData<T>> get actualMap;

  /// Registers [value] with [id] in [actualMap].
  ///
  /// Checks for duplicate data for [id].
  void registerValue(Uri uri, int offset, Id id, T? value, Object object) {
    if (value != null) {
      ActualData<T> newData = new ActualData<T>(id, value, uri, offset, object);
      if (actualMap.containsKey(id)) {
        ActualData<T> existingData = actualMap[id]!;
        ActualData<T>? mergedData = mergeData(existingData, newData);
        if (mergedData != null) {
          actualMap[id] = mergedData;
        } else {
          report(
              uri,
              offset,
              "Duplicate id ${id}, value=$value, object=$object "
              "(${object.runtimeType})");
          report(
              uri,
              offset,
              "Duplicate id ${id}, value=${existingData.value}, "
              "object=${existingData.object} "
              "(${existingData.object.runtimeType})");
          fail("Duplicate id $id.");
        }
      } else {
        actualMap[id] = newData;
      }
    }
  }

  ActualData<T>? mergeData(ActualData<T> value1, ActualData<T> value2) => null;

  /// Called to report duplicate errors.
  void report(Uri uri, int offset, String message);

  /// Called to raise an exception on duplicate errors.
  void fail(String message);
}
