// 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/context/context.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type_provider.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/summary2/bundle_reader.dart';
import 'package:analyzer/src/summary2/linked_library_context.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';

class LinkedElementFactory {
  final AnalysisContextImpl analysisContext;
  final AnalysisSessionImpl analysisSession;
  final Reference rootReference;
  final Map<String, List<Reference>> linkingExports = {};
  final Map<String, LibraryReader> libraryReaders = {};

  LinkedElementFactory(
    this.analysisContext,
    this.analysisSession,
    this.rootReference,
  ) {
    ArgumentError.checkNotNull(analysisContext, 'analysisContext');
    ArgumentError.checkNotNull(analysisSession, 'analysisSession');
    _declareDartCoreDynamicNever();
  }

  Reference get dynamicRef {
    return rootReference.getChild('dart:core').getChild('dynamic');
  }

  bool get hasDartCore {
    return libraryReaders.containsKey('dart:core');
  }

  void addBundle(BundleReader bundle) {
    addLibraries(bundle.libraryMap);
  }

  void addLibraries(Map<String, LibraryReader> libraries) {
    libraryReaders.addAll(libraries);
  }

  Namespace buildExportNamespace(Uri uri) {
    var exportedNames = <String, Element>{};

    var exportedReferences = exportsOfLibrary('$uri');
    for (var exportedReference in exportedReferences) {
      var element = elementOfReference(exportedReference);
      // TODO(scheglov) Remove after https://github.com/dart-lang/sdk/issues/41212
      if (element == null) {
        throw StateError(
          '[No element]'
          '[uri: $uri]'
          '[exportedReferences: $exportedReferences]'
          '[exportedReference: $exportedReference]',
        );
      }
      exportedNames[element.name!] = element;
    }

    return Namespace(exportedNames);
  }

  LibraryElementImpl? createLibraryElementForLinking(
    LinkedLibraryContext libraryContext,
  ) {
    var sourceFactory = analysisContext.sourceFactory;
    var libraryUriStr = libraryContext.uriStr;
    var librarySource = sourceFactory.forUri(libraryUriStr);

    // The URI cannot be resolved, we don't know the library.
    if (librarySource == null) return null;

    var definingUnitContext = libraryContext.units[0];
    var definingUnitNode = definingUnitContext.unit!;

    // TODO(scheglov) Do we need this?
    var name = '';
    var nameOffset = -1;
    var nameLength = 0;
    for (var directive in definingUnitNode.directives) {
      if (directive is LibraryDirective) {
        name = directive.name.components.map((e) => e.name).join('.');
        nameOffset = directive.name.offset;
        nameLength = directive.name.length;
        break;
      }
    }

    var libraryElement = LibraryElementImpl.forLinkedNode(
      analysisContext,
      analysisSession,
      name,
      nameOffset,
      nameLength,
      definingUnitContext,
      libraryContext.reference,
      definingUnitNode,
    );
    _setLibraryTypeSystem(libraryElement);

    var units = <CompilationUnitElementImpl>[];
    var unitContainerRef = libraryContext.reference.getChild('@unit');
    for (var unitContext in libraryContext.units) {
      var unitNode = unitContext.unit as CompilationUnitImpl;

      var unitSource = sourceFactory.forUri(unitContext.uriStr);
      if (unitSource == null) continue;

      var unitElement = CompilationUnitElementImpl.forLinkedNode(
        libraryElement,
        unitContext,
        unitContext.reference,
        unitNode,
      );
      unitElement.lineInfo = unitNode.lineInfo;
      unitElement.source = unitSource;
      unitElement.librarySource = librarySource;
      unitElement.uri = unitContext.partUriStr;
      units.add(unitElement);
      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
    }

    libraryElement.definingCompilationUnit = units[0];
    libraryElement.parts = units.skip(1).toList();
    libraryContext.reference.element = libraryElement;

    return libraryElement;
  }

  LibraryElementImpl? createLibraryElementForReading(String uriStr) {
    var sourceFactory = analysisContext.sourceFactory;
    var librarySource = sourceFactory.forUri(uriStr);

    // The URI cannot be resolved, we don't know the library.
    if (librarySource == null) return null;

    var reader = libraryReaders[uriStr];
    if (reader == null) {
      throw ArgumentError(
        'Missing library: $uriStr\n'
        'Available libraries: ${libraryReaders.keys.toList()}',
      );
    }

    var libraryContext = LinkedLibraryContext(this, uriStr, reader.reference);
    var unitContainerRef = reader.reference.getChild('@unit');

    var unitContexts = <LinkedUnitContext>[];
    var indexInLibrary = 0;
    var unitReaders = reader.units;
    for (var unitReader in unitReaders) {
      var unitReference = unitContainerRef.getChild(unitReader.uriStr);
      var unitContext = LinkedUnitContext(
        libraryContext,
        indexInLibrary++,
        unitReader.partUriStr,
        unitReader.uriStr,
        unitReference,
        unitReader.isSynthetic,
        unit: unitReader.unit,
        unitReader: unitReader,
      );
      unitContexts.add(unitContext);
      libraryContext.units.add(unitContext);
    }

    var definingUnitContext = unitContexts[0];
    var libraryElement = LibraryElementImpl.forLinkedNode(
      analysisContext,
      analysisSession,
      reader.name,
      reader.nameOffset,
      reader.nameLength,
      definingUnitContext,
      reader.reference,
      unitReaders.first.unit,
    );
    _setLibraryTypeSystem(libraryElement);

    var units = <CompilationUnitElementImpl>[];
    for (var unitContext in unitContexts) {
      var unitNode = unitContext.unit as CompilationUnitImpl;

      var unitSource = sourceFactory.forUri(unitContext.uriStr);
      if (unitSource == null) continue;

      var unitElement = CompilationUnitElementImpl.forLinkedNode(
        libraryElement,
        unitContext,
        unitContext.reference,
        unitNode,
      );
      unitElement.lineInfo = unitNode.lineInfo;
      unitElement.source = unitSource;
      unitElement.librarySource = librarySource;
      unitElement.uri = unitContext.partUriStr;
      units.add(unitElement);
      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
    }

    libraryElement.definingCompilationUnit = units[0];
    libraryElement.parts = units.skip(1).toList();
    reader.reference.element = libraryElement;

    return libraryElement;
  }

  void createTypeProviders(
    LibraryElementImpl /*!*/ dartCore,
    LibraryElementImpl /*!*/ dartAsync,
  ) {
    if (analysisContext.hasTypeProvider) {
      return;
    }

    analysisContext.setTypeProviders(
      legacy: TypeProviderImpl(
        coreLibrary: dartCore,
        asyncLibrary: dartAsync,
        isNonNullableByDefault: false,
      ),
      nonNullableByDefault: TypeProviderImpl(
        coreLibrary: dartCore,
        asyncLibrary: dartAsync,
        isNonNullableByDefault: true,
      ),
    );

    // During linking we create libraries when typeProvider is not ready.
    // Update these libraries now, when typeProvider is ready.
    for (var reference in rootReference.children) {
      var libraryElement = reference.element as LibraryElementImpl?;
      if (libraryElement != null && !libraryElement.hasTypeProviderSystemSet) {
        _setLibraryTypeSystem(libraryElement);
      }
    }
  }

  Element? elementOfReference(Reference reference) {
    if (reference.element != null) {
      return reference.element;
    }
    if (reference.parent == null) {
      return null;
    }

    if (reference.isLibrary) {
      var uriStr = reference.name;
      return createLibraryElementForReading(uriStr);
    }

    var parent = reference.parent!.parent!;
    var parentElement = elementOfReference(parent);

    // Named formal parameters are created when we apply resolution to the
    // executable declaration, e.g. a constructor, or a method.
    if (reference.isParameter) {
      (parentElement as ExecutableElement).parameters;
      assert(reference.element != null);
      return reference.element;
    }

    // The default constructor might be synthetic, and has no node.
    // TODO(scheglov) We resynthesize all constructors here.
    if (reference.isConstructor && reference.name == '') {
      return (parentElement as ClassElement).unnamedConstructor;
    }

    if (parentElement is EnumElementImpl) {
      parentElement.constants;
      assert(reference.element != null);
      return reference.element;
    }

    if (reference.element != null) {
      return reference.element;
    }

    if (reference.isUnit) {
      assert(reference.element != null);
      return reference.element;
    }

    if (reference.isPrefix) {
      (parentElement as LibraryElement).prefixes;
      assert(reference.element != null);
      return reference.element;
    }

    // For class, mixin, extension - index members.
    var parentNodeAccessor = parent.nodeAccessor;
    // TODO(scheglov) https://github.com/dart-lang/sdk/issues/44841
    if (parentNodeAccessor == null) {
      var parentNodeCode = '<unknown>';
      try {
        parentNodeCode = '${parent.node}';
      } catch (_) {}
      throw '[reference: $reference]'
          '[parent: $parent]'
          '[parentNodeCode: $parentNodeCode]';
    } else {
      parentNodeAccessor.readIndex();
    }

    // For any element - class, method, etc - read the node.
    var node = reference.nodeAccessor!.node;

    if (node is ClassDeclaration) {
      ClassElementImpl.forLinkedNode(
          parentElement as CompilationUnitElementImpl, reference, node);
      assert(reference.element != null);
      return reference.element;
    } else if (node is ClassTypeAlias) {
      ClassElementImpl.forLinkedNode(
          parentElement as CompilationUnitElementImpl, reference, node);
      assert(reference.element != null);
      return reference.element;
    } else if (node is ConstructorDeclarationImpl) {
      ConstructorElementImpl.forLinkedNode(
          parentElement as ClassElementImpl, reference, node);
      var element = reference.element as ConstructorElementImpl;
      return element;
    } else if (node is EnumDeclaration) {
      EnumElementImpl.forLinkedNode(
          parentElement as CompilationUnitElementImpl, reference, node);
      assert(reference.element != null);
      return reference.element;
    } else if (node is ExtensionDeclarationImpl) {
      ExtensionElementImpl.forLinkedNode(
          parentElement as CompilationUnitElementImpl, reference, node);
      assert(reference.element != null);
      return reference.element;
    } else if (node is FieldDeclaration) {
      var variable = _variableDeclaration(node.fields, reference.name);
      if (variable.isConst) {
        ConstFieldElementImpl.forLinkedNode(
            parentElement as ElementImpl, reference, variable);
      } else {
        FieldElementImpl.forLinkedNodeFactory(
            parentElement as ElementImpl, reference, variable);
      }
      assert(reference.element != null);
      return reference.element;
    } else if (node is FunctionDeclaration) {
      if (node.propertyKeyword != null) {
        _topLevelPropertyAccessor(parent,
            parentElement as CompilationUnitElementImpl, reference, node);
      } else {
        FunctionElementImpl.forLinkedNode(
            parentElement as CompilationUnitElementImpl, reference, node);
      }
      assert(reference.element != null);
      return reference.element;
    } else if (node is FunctionTypeAlias || node is GenericTypeAlias) {
      TypeAliasElementImpl.forLinkedNodeFactory(
          parentElement as CompilationUnitElementImpl,
          reference,
          node as TypeAlias);
      assert(reference.element != null);
      return reference.element;
    } else if (node is MethodDeclaration) {
      if (node.propertyKeyword != null) {
        _classPropertyAccessor(
            parent, parentElement as ElementImpl, reference, node);
      } else {
        MethodElementImpl.forLinkedNode(
            parentElement as TypeParameterizedElementMixin, reference, node);
      }
      assert(reference.element != null);
      return reference.element;
    } else if (node is MixinDeclaration) {
      MixinElementImpl.forLinkedNode(
          parentElement as CompilationUnitElementImpl, reference, node);
      assert(reference.element != null);
      return reference.element;
    } else if (node is TopLevelVariableDeclaration) {
      var variable = _variableDeclaration(node.variables, reference.name);
      if (variable.isConst) {
        ConstTopLevelVariableElementImpl.forLinkedNode(
            parentElement as ElementImpl, reference, variable);
      } else {
        TopLevelVariableElementImpl.forLinkedNode(
            parentElement as CompilationUnitElementImpl, reference, variable);
      }
      assert(reference.element != null);
      return reference.element;
    }

    throw UnimplementedError('$reference');
  }

  List<Reference> exportsOfLibrary(String uriStr) {
    var linkingExportedReferences = linkingExports[uriStr];
    if (linkingExportedReferences != null) {
      return linkingExportedReferences;
    }

    var library = libraryReaders[uriStr];
    if (library == null) return const [];

    return library.exports;
  }

  bool hasLibrary(String uriStr) {
    return libraryReaders[uriStr] != null;
  }

  bool isLibraryUri(String uriStr) {
    var libraryContext = libraryReaders[uriStr]!;
    return !libraryContext.hasPartOfDirective;
  }

  LibraryElementImpl? libraryOfUri(String uriStr) {
    var reference = rootReference.getChild(uriStr);
    return elementOfReference(reference) as LibraryElementImpl?;
  }

  LibraryElementImpl libraryOfUri2(String uriStr) {
    var element = libraryOfUri(uriStr);
    if (element == null) {
      throw StateError('No library: $uriStr');
    }
    return element;
  }

  /// We have linked the bundle, and need to disconnect its libraries, so
  /// that the client can re-add the bundle, this time read from bytes.
  void removeBundle(Set<String> uriStrSet) {
    removeLibraries(uriStrSet);

    // This is the bundle with dart:core and dart:async, based on full ASTs.
    // To link them, the linker set the type provider. We are removing these
    // libraries, and we should also remove the type provider.
    if (uriStrSet.contains('dart:core')) {
      if (!uriStrSet.contains('dart:async')) {
        throw StateError(
          'Expected to link dart:core and dart:async together: '
          '${uriStrSet.toList()}',
        );
      }
      if (libraryReaders.isNotEmpty) {
        throw StateError(
          'Expected to link dart:core and dart:async first: '
          '${libraryReaders.keys.toList()}',
        );
      }
      analysisContext.clearTypeProvider();
      _declareDartCoreDynamicNever();
    }
  }

  /// Remove libraries with the specified URIs from the reference tree, and
  /// any session level caches.
  void removeLibraries(Set<String> uriStrSet) {
    for (var uriStr in uriStrSet) {
      libraryReaders.remove(uriStr);
      linkingExports.remove(uriStr);
      rootReference.removeChild(uriStr);
    }

    analysisSession.classHierarchy.removeOfLibraries(uriStrSet);
    analysisSession.inheritanceManager.removeOfLibraries(uriStrSet);
  }

  void _classPropertyAccessor(
    Reference parentReference,
    ElementImpl parentElement,
    Reference reference,
    MethodDeclaration node,
  ) {
    var accessor = PropertyAccessorElementImpl.forLinkedNode(
        parentElement, reference, node);

    var name = reference.name;
    var fieldRef = parentReference.getChild('@field').getChild(name);
    var field = fieldRef.element as FieldElementImpl?;
    if (field == null) {
      field = FieldElementImpl(name, -1);
      fieldRef.element = field;
      field.enclosingElement = parentElement;
      field.isSynthetic = true;
      field.isFinal = node.isGetter;
      field.isStatic = accessor.isStatic;
    } else {
      field.isFinal = false;
    }

    var isSetter = node.isSetter;
    if (isSetter) {
      field.isFinal = false;
    }

    accessor.variable = field;
    if (isSetter) {
      field.setter = accessor;
    } else {
      field.getter = accessor;
    }
  }

  void _declareDartCoreDynamicNever() {
    var dartCoreRef = rootReference.getChild('dart:core');
    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
  }

  void _setLibraryTypeSystem(LibraryElementImpl libraryElement) {
    // During linking we create libraries when typeProvider is not ready.
    // And if we link dart:core and dart:async, we cannot create it.
    // We will set typeProvider later, during [createTypeProviders].
    if (!analysisContext.hasTypeProvider) {
      return;
    }

    var isNonNullable = libraryElement.isNonNullableByDefault;
    libraryElement.typeProvider = isNonNullable
        ? analysisContext.typeProviderNonNullableByDefault
        : analysisContext.typeProviderLegacy;
    libraryElement.typeSystem = isNonNullable
        ? analysisContext.typeSystemNonNullableByDefault
        : analysisContext.typeSystemLegacy;
    libraryElement.hasTypeProviderSystemSet = true;

    libraryElement.createLoadLibraryFunction();
  }

  void _topLevelPropertyAccessor(
    Reference parentReference,
    CompilationUnitElementImpl parentElement,
    Reference reference,
    FunctionDeclaration node,
  ) {
    var accessor = PropertyAccessorElementImpl.forLinkedNode(
        parentElement, reference, node);

    var name = reference.name;
    var fieldRef = parentReference.getChild('@field').getChild(name);
    var field = fieldRef.element as TopLevelVariableElementImpl?;
    if (field == null) {
      field = TopLevelVariableElementImpl(name, -1);
      fieldRef.element = field;
      field.enclosingElement = parentElement;
      field.isFinal = true;
      field.isSynthetic = true;
    }

    var isSetter = node.isSetter;
    if (isSetter) {
      field.isFinal = false;
    }

    accessor.variable = field;
    if (isSetter) {
      field.setter = accessor;
    } else {
      field.getter = accessor;
    }
  }

  static VariableDeclaration _variableDeclaration(
    VariableDeclarationList variableList,
    String name,
  ) {
    for (var variable in variableList.variables) {
      if (variable.name.name == name) {
        return variable;
      }
    }
    throw StateError('No "$name" in: $variableList');
  }
}
