// 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/src/dart/element/element.dart';
import 'package:meta/meta.dart';

/// Indirection between a name and the corresponding [FragmentImpl].
///
/// References are organized in a prefix tree.
/// Each reference knows its parent, children, and the [FragmentImpl].
///
///      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 [FragmentImpl].
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 [FragmentImpl], or `null` if a named container.
  FragmentImpl? element;

  /// The corresponding [Element], or `null` if a named container.
  Element? 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;
  }
}
