// Copyright (c) 2019, 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:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/element2.dart';
import 'package:meta/meta.dart';

/// Indirection between a name and the corresponding [Element].
///
/// References are organized in a prefix tree.
/// Each reference knows its parent, children, and the [Element].
///
///      Library:
///         URI of library
///
///      Class:
///         Reference of the enclosing library
///         "@class"
///         Name of the class
///
///      Method:
///         Reference of the enclosing class
///         "@method"
///         Name of the method
///
/// There is only one reference object per [Element].
class Reference {
  /// The name of the container used for duplicate declarations.
  static const _defName = '@def';

  /// The parent of this reference, or `null` if the root.
  Reference? parent;

  /// The simple name of the reference in its [parent].
  String name;

  /// The corresponding [Element], or `null` if a named container.
  Element? element;

  /// The corresponding [Element2], or `null` if a named container.
  Element2? element2;

  /// Temporary index used during serialization and linking.
  int? index;

  // null, Reference or Map<String, Reference>.
  Object? _childrenUnion;

  Reference.root() : this._(null, '');

  Reference._(this.parent, this.name);

  Iterable<Reference> get children {
    var childrenUnion = _childrenUnion;
    if (childrenUnion == null) return const [];
    if (childrenUnion is Reference) return [childrenUnion];
    return (childrenUnion as Map<String, Reference>).values;
  }

  @visibleForTesting
  Object? get childrenUnionForTesting => _childrenUnion;

  /// The name of the element that this reference represents.
  ///
  /// Normally, this is [name]. But in case of duplicate declarations, such
  /// as augmentations (which is allowed by the specification), or invalid
  /// code, the actual name is the name of the parent of the duplicates
  /// container `@def`.
  String get elementName {
    if (parent?.name == _defName) {
      return parent!.parent!.name;
    }
    return name;
  }

  bool get isLibrary => parent?.isRoot == true;

  bool get isPrefix => parent?.name == '@prefix';

  bool get isRoot => parent == null;

  bool get isSetter => parent?.name == '@setter';

  /// The parent that is not a container like `@method`.
  ///
  /// Usually this is the parent of the parent.
  /// @class::A::@method::foo -> @class::A
  ///
  /// But if this is a duplicates, we go two more levels up.
  /// @class::A::@method::foo::@def::0 -> @class::A
  Reference get parentNotContainer {
    // Should be `@method`, `@constructor`, etc.
    var containerInParent = parent!;

    // Skip the duplicates container.
    if (containerInParent.name == _defName) {
      containerInParent = containerInParent.parent!.parent!;
    }

    return containerInParent.parent!;
  }

  /// Return the child with the given name, or `null` if does not exist.
  Reference? operator [](String name) {
    var childrenUnion = _childrenUnion;
    if (childrenUnion == null) return null;
    if (childrenUnion is Reference) {
      if (childrenUnion.name == name) return childrenUnion;
      return null;
    }
    return (childrenUnion as Map<String, Reference>)[name];
  }

  /// Adds a new child with the given [name].
  ///
  /// This method should be used when a new declaration of an element with
  /// this name is processed. If there is no existing child with this name,
  /// this method works exactly as [getChild]. If there is a duplicate, which
  /// should happen rarely, an intermediate `@def` container is added, the
  /// existing child is transferred to it and renamed to `0`, then a new child
  /// is added with name `1`. Additional duplicate children get names `2`, etc.
  Reference addChild(String name) {
    var child = Reference._(null, name);
    addChildReference(name, child);
    return child;
  }

  /// Transfers [child] to this parent.
  void addChildReference(String name, Reference child) {
    child.parent = this;

    var existing = this[name];

    // If not a duplicate.
    if (existing == null) {
      _addChild(name, child);
      return;
    }

    var def = existing[_defName];

    // If no duplicates container yet.
    if (def == null) {
      removeChild(name); // existing
      def = getChild(name).getChild(_defName);
      existing.parent = def;
      existing.name = '0';
      def._addChild(existing.name, existing);
    }

    // Add a new child to the duplicates container.
    child.parent = def;
    child.name = '${def.children.length}';
    def._addChild(child.name, child);
  }

  /// Return the child with the given name, create if does not exist yet.
  Reference getChild(String name) {
    var childrenUnion = _childrenUnion;
    if (childrenUnion == null) {
      // 0 -> 1 children.
      return _childrenUnion = Reference._(this, name);
    }
    if (childrenUnion is Reference) {
      if (childrenUnion.name == name) return childrenUnion;

      // 1 -> 2 children.
      var childrenUnionAsMap = _childrenUnion = <String, Reference>{};
      childrenUnionAsMap[childrenUnion.name] = childrenUnion;
      return childrenUnionAsMap[name] = Reference._(this, name);
    }
    return (childrenUnion as Map<String, Reference>)[name] ??=
        Reference._(this, name);
  }

  /// Returns children with the given name.
  /// Usually returns zero or one child.
  /// But in case of duplicates will return more than one.
  List<Reference> getChildrenByName(String name) {
    var result = this[name];

    // No such child yet.
    if (result == null) {
      return const [];
    }

    // Maybe has the container with duplicates.
    if (result[_defName] case var defContainer?) {
      return defContainer.children.toList();
    }

    // Should be the only child with such name.
    return [result];
  }

  Reference? removeChild(String name) {
    var childrenUnion = _childrenUnion;
    if (childrenUnion == null) return null;
    if (childrenUnion is Reference) {
      if (childrenUnion.name == name) {
        // 1 -> 0 children.
        _childrenUnion = null;
        return childrenUnion;
      }
      return null;
    }
    var childrenUnionAsMap = childrenUnion as Map<String, Reference>;
    var result = childrenUnionAsMap.remove(name);
    if (childrenUnionAsMap.length == 1) {
      // 2 -> 1 children.
      _childrenUnion = childrenUnionAsMap.values.single;
    }
    return result;
  }

  @override
  String toString() => parent == null ? 'root' : '$parent::$name';

  void _addChild(String name, Reference child) {
    var childrenUnion = _childrenUnion;
    if (childrenUnion == null) {
      // 0 -> 1 children.
      _childrenUnion = child;
      return;
    }
    if (childrenUnion is Reference) {
      // 1 -> 2 children.
      var childrenUnionAsMap = _childrenUnion = <String, Reference>{};
      childrenUnionAsMap[childrenUnion.name] = childrenUnion;
      childrenUnionAsMap[name] = child;
      return;
    }
    (childrenUnion as Map<String, Reference>)[name] ??= child;
  }
}
