// 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/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/summary2/scope.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 parent of this reference, or `null` if the root.
  final Reference? parent;

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

  /// The node accessor, used to read nodes lazily.
  /// Or `null` if a named container.
  ReferenceNodeAccessor? nodeAccessor;

  /// The corresponding [AstNode], or `null` if a named container.
  /// TODO(scheglov) remove it
  AstNode? node;

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

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

  Map<String, Reference>? _children;

  /// If this reference is an import prefix, the scope of this prefix.
  Scope? prefixScope;

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

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

  Iterable<Reference> get children {
    if (_children != null) {
      return _children!.values;
    }
    return const [];
  }

  bool get isClass => parent != null && parent!.name == '@class';

  bool get isConstructor => parent != null && parent!.name == '@constructor';

  bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core';

  bool get isEnum => parent != null && parent!.name == '@enum';

  bool get isGetter => parent != null && parent!.name == '@getter';

  bool get isLibrary => parent != null && parent!.isRoot;

  bool get isParameter => parent != null && parent!.name == '@parameter';

  bool get isPrefix => parent != null && parent!.name == '@prefix';

  bool get isRoot => parent == null;

  bool get isSetter => parent != null && parent!.name == '@setter';

  bool get isTypeAlias => parent != null && parent!.name == '@typeAlias';

  bool get isUnit => parent != null && parent!.name == '@unit';

  /// Return the child with the given name, or `null` if does not exist.
  Reference? operator [](String name) {
    return _children != null ? _children![name] : null;
  }

  /// Return the child with the given name, create if does not exist yet.
  Reference getChild(String name) {
    var map = _children ??= <String, Reference>{};
    return map[name] ??= Reference._(this, name);
  }

  /// If the reference has element, and it is for the [node], return `true`.
  ///
  /// The element might be not `null`, but the node is different in case of
  /// duplicate declarations.
  bool hasElementFor(AstNode node) {
    if (element != null && this.node == node) {
      return true;
    } else {
      if (this.node == null) {
        this.node = node;
      }
      return false;
    }
  }

  void removeChild(String name) {
    _children!.remove(name);
  }

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

abstract class ReferenceNodeAccessor {
  /// Return the node that corresponds to this [Reference], read it if not yet.
  AstNode get node;

  /// Fill [Reference.nodeAccessor] for children.
  ///
  /// TODO(scheglov) only class reader has a meaningful implementation.
  void readIndex();
}
