// 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/analysis/results.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer_plugin/src/utilities/change_builder/dart/syntactic_scope.dart';
import 'package:meta/meta.dart';

ImportLibraryRequest importLibraryElementImpl({
  @required ResolvedLibraryResult targetResolvedLibrary,
  @required String targetPath,
  @required int targetOffset,
  @required LibraryElement requestedLibrary,
  @required String requestedName,
}) {
  var targetLibrary = targetResolvedLibrary.element;

  var requestedLibraryUri = requestedLibrary.source.uri;
  var requestedElement = requestedLibrary.exportNamespace.get(requestedName);
  var requestedElementUri = requestedElement.librarySource.uri;

  // If the element is defined in this library, then no prefix needed.
  if (targetLibrary == requestedElement.library) {
    return ImportLibraryRequest(null, null);
  }

  var requestedElements = requestedLibrary.exportNamespace.definedNames;
  _removeEntryForDynamic(requestedElements);

  // Find URIs of all libraries that import the requested name into the target.
  var unprefixedNameUriSet = Set<Uri>();
  for (var import in targetLibrary.imports) {
    var definedNames = import.namespace.definedNames;
    if (import.prefix == null) {
      var element = definedNames[requestedName];
      if (element != null) {
        unprefixedNameUriSet.add(element.librarySource.uri);
      }
    }
  }

  // Find names that will be shadowed by a new unprefixed import.
  var collector = NotSyntacticScopeReferencedNamesCollector(
    targetResolvedLibrary.element,
    requestedElements.keys.toSet(),
  );
  for (var resolvedUnit in targetResolvedLibrary.units) {
    resolvedUnit.unit.accept(collector);
  }

  // Find names that will shadow unprefixed references.
  var scopeNames = Set<String>();
  targetLibrary.accept(_TopLevelNamesCollector(scopeNames));
  for (var resolvedUnit in targetResolvedLibrary.units) {
    if (resolvedUnit.path == targetPath) {
      resolvedUnit.unit.accept(
        SyntacticScopeNamesCollector(scopeNames, targetOffset),
      );
    }
  }

  var canUseUnprefixedImport = true;

  // If a name is inherited, it will be shadowed by a new unprefixed import.
  if (collector.inheritedNames.isNotEmpty) {
    canUseUnprefixedImport = false;
  }

  // If a name is imported, and it is not the same as the one from the
  // requested library, then a new unprefixed import will cause ambiguity.
  for (var name in collector.importedNames.keys) {
    var importedUri = collector.importedNames[name];
    var requestedUri = requestedElements[name]?.librarySource?.uri;
    if (requestedUri != importedUri) {
      canUseUnprefixedImport = false;
      break;
    }
  }

  // If syntactic scope at the offset has the requested name, then the name
  // from an unprefixed import will be shadowed.
  if (scopeNames.contains(requestedName)) {
    canUseUnprefixedImport = false;
  }

  // If the requested name is ambiguous from existing unprefixed imports,
  // or is not the same element as the one from the requested library, then
  // we cannot use unprefixed import.
  if (unprefixedNameUriSet.isNotEmpty) {
    if (unprefixedNameUriSet.length > 1 ||
        unprefixedNameUriSet.first != requestedElementUri) {
      canUseUnprefixedImport = false;
    }
  }

  // Find import prefixes with which the name is ambiguous.
  var ambiguousWithImportPrefixes = Set<String>();
  for (var import in targetLibrary.imports) {
    var definedNames = import.namespace.definedNames;
    if (import.prefix != null) {
      var prefix = import.prefix.name;
      var prefixedName = '$prefix.$requestedName';
      var importedElement = definedNames[prefixedName];
      if (importedElement != null &&
          importedElement.librarySource.uri != requestedElementUri) {
        ambiguousWithImportPrefixes.add(prefix);
      }
    }
  }

  // Check for existing imports of the requested library.
  for (var import in targetLibrary.imports) {
    if (import.importedLibrary.source.uri == requestedLibraryUri) {
      var importedNames = import.namespace.definedNames;
      if (import.prefix == null) {
        if (canUseUnprefixedImport &&
            importedNames.containsKey(requestedName)) {
          return ImportLibraryRequest(null, null);
        }
      } else {
        var prefix = import.prefix.name;
        var prefixedName = '$prefix.$requestedName';
        if (importedNames.containsKey(prefixedName) &&
            !ambiguousWithImportPrefixes.contains(prefix)) {
          return ImportLibraryRequest(null, prefix);
        }
      }
    }
  }

  // If the name cannot be used without import prefix, generate one.
  String prefix;
  if (!canUseUnprefixedImport) {
    prefix = 'prefix';
    for (var index = 0;; index++) {
      prefix = 'prefix$index';
      if (!collector.referencedNames.contains(prefix)) {
        break;
      }
    }
  }

  return ImportLibraryRequest(requestedLibraryUri, prefix);
}

/// The type `dynamic` is part of 'dart:core', but has no library.
void _removeEntryForDynamic(Map<String, Element> requestedElements) {
  requestedElements.removeWhere((_, element) {
    if (element.librarySource == null) {
      assert(element.displayName == 'dynamic');
      return true;
    }
    return false;
  });
}

/// Information about a library to import.
class ImportLibraryRequest {
  /// The URI of the library to import, or `null` if the requested library is
  /// already imported, with the [prefix], so no new import is required.
  final Uri uri;

  /// The prefix with which ths requested library is already imported,
  /// or should be imported, or `null` is no prefix is necessary.
  final String prefix;

  ImportLibraryRequest(this.uri, this.prefix);
}

/// Element visitor that collects names of top-level elements.
class _TopLevelNamesCollector extends GeneralizingElementVisitor<void> {
  final Set<String> names;

  _TopLevelNamesCollector(this.names);

  @override
  void visitElement(Element element) {
    if (element is LibraryElement || element is CompilationUnitElement) {
      super.visitElement(element);
    } else if (element is ImportElement) {
      var prefix = element.prefix?.displayName;
      if (prefix != null) {
        names.add(prefix);
      }
    } else if (element.enclosingElement is CompilationUnitElement) {
      names.add(element.displayName);
    }
  }
}
