// Copyright (c) 2016, 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/declared_variables.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/name_filter.dart';

/**
 * Create a [LinkedLibraryBuilder] corresponding to the given [definingUnitUri]
 * and [definingUnit], which should be the defining compilation unit for a
 * library. Compilation units referenced by the defining compilation unit via
 * `part` declarations will be retrieved using [getPart].  Public namespaces
 * for libraries referenced by the defining compilation unit via `import`
 * declarations (and files reachable from them via `part` and `export`
 * declarations) will be retrieved using [getImport].
 */
LinkedLibraryBuilder prelink(
    String definingUnitUri,
    UnlinkedUnit definingUnit,
    GetPartCallback getPart,
    GetImportCallback getImport,
    DeclaredVariables declaredVariables) {
  return new _Prelinker(
          definingUnitUri, definingUnit, getPart, getImport, declaredVariables)
      .prelink();
}

/**
 * Type of the callback used by the prelinker to obtain public namespace
 * information about libraries with the given [absoluteUri] imported by the
 * library to be prelinked (and the transitive closure of parts and exports
 * reachable from those libraries).
 *
 * If no file exists at the given uri, `null` should be returned.
 */
typedef UnlinkedPublicNamespace GetImportCallback(String absoluteUri);

/**
 * Type of the callback used by the prelinker to obtain unlinked summaries of
 * part files of the library to be prelinked.
 *
 * If no file exists at the given uri, `null` should be returned.
 */
typedef UnlinkedUnit GetPartCallback(String absoluteUri);

/**
 * A [_Meaning] representing a class.
 */
class _ClassMeaning extends _Meaning {
  final _Namespace namespace;

  _ClassMeaning(int unit, int dependency, int numTypeParameters, this.namespace)
      : super(unit, ReferenceKind.classOrEnum, dependency, numTypeParameters);
}

/**
 * A node in computing exported namespaces.
 */
class _ExportNamespace {
  static int nextId = 0;

  /**
   * The export namespace, full (with all exports included), or partial (with
   * public namespace, and only some of the exports included).
   */
  final _Namespace namespace;

  /**
   * This field is set to non-zero when we start computing the export namespace
   * for the corresponding library, and is set back to zero when we finish
   * computation.
   */
  int id = 0;

  /**
   * Whether the [namespace] is full, so we don't need chasing exports.
   */
  bool isFull = false;

  _ExportNamespace(this.namespace);
}

/**
 * A [_Meaning] stores all the information necessary to find the declaration
 * referred to by a name in a namespace.
 */
class _Meaning {
  /**
   * Which unit in the dependent library contains the declared entity.
   */
  final int unit;

  /**
   * The kind of entity being referred to.
   */
  final ReferenceKind kind;

  /**
   * Which of the dependencies of the library being prelinked contains the
   * declared entity.
   */
  final int dependency;

  /**
   * If the entity being referred to is generic, the number of type parameters
   * it accepts.  Otherwise zero.
   */
  final int numTypeParameters;

  _Meaning(this.unit, this.kind, this.dependency, this.numTypeParameters);

  /**
 * Encode this [_Meaning] as a [LinkedExportName], using the given [name].
 */
  LinkedExportName encodeExportName(String name) {
    return new LinkedExportNameBuilder(
        name: name, dependency: dependency, unit: unit, kind: kind);
  }

/**
   * Encode this [_Meaning] as a [LinkedReference].
   */
  LinkedReferenceBuilder encodeReference() {
    return new LinkedReferenceBuilder(
        unit: unit,
        kind: kind,
        dependency: dependency,
        numTypeParameters: numTypeParameters);
  }
}

/**
 * Mapping from names to corresponding unique [_Meaning]s.
 */
class _Namespace {
  final Set<String> namesWithConflictingDefinitions = new Set<String>();
  final Set<String> libraryNames = new Set<String>();
  final Map<String, _Meaning> map = <String, _Meaning>{};

  /**
   * Return the [_Meaning] of the name, or `null` is not defined.
   */
  _Meaning operator [](String name) {
    return map[name];
  }

  /**
   * Define that the [name] has the given [value].  If the [name] already been
   * defined with a different value, then it becomes undefined.
   */
  void add(String name, _Meaning value) {
    // Already determined to be a conflict.
    if (namesWithConflictingDefinitions.contains(name)) {
      return;
    }

    _Meaning currentValue = map[name];
    if (currentValue == null) {
      map[name] = value;
    } else if (currentValue == value) {
      // The same value, ignore.
    } else {
      // A conflict, remember it, and un-define the name.
      namesWithConflictingDefinitions.add(name);
      map.remove(name);
    }
  }

  /**
   * Return `true` if the [name] was defined before [rememberLibraryNames]
   * invocation.
   */
  bool definesLibraryName(String name) => libraryNames.contains(name);

  /**
   * Return `true` if the [name] is already defined.
   */
  bool definesName(String name) => map.containsKey(name);

  /**
   * Apply [f] to each name-meaning pair.
   */
  void forEach(void f(String key, _Meaning value)) {
    map.forEach(f);
  }

  /**
   * This method should be invoked after defining all names that are defined
   * in a library, before defining imported names.
   */
  void rememberLibraryNames() {
    libraryNames.addAll(map.keys);
  }
}

/**
 * A [_Meaning] representing a prefix introduced by an import directive.
 */
class _PrefixMeaning extends _Meaning {
  final _Namespace namespace = new _Namespace();

  _PrefixMeaning() : super(0, ReferenceKind.prefix, 0, 0);
}

/**
 * Helper class containing temporary data structures needed to prelink a single
 * library.
 */
class _Prelinker {
  final String definingUnitUri;
  final UnlinkedUnit definingUnit;
  final GetPartCallback getPart;
  final GetImportCallback getImport;
  final DeclaredVariables declaredVariables;

  /**
   * Cache of values returned by [getImport].
   */
  final Map<String, UnlinkedPublicNamespace> importCache =
      <String, UnlinkedPublicNamespace>{};

  /**
   * Cache of values returned by [getPart].
   */
  final Map<String, UnlinkedUnit> partCache = <String, UnlinkedUnit>{};

  /**
   * Names defined inside the library being prelinked.
   */
  final _Namespace privateNamespace = new _Namespace()
    ..add('dynamic', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0))
    ..add('void', new _Meaning(0, ReferenceKind.classOrEnum, 0, 0));

  /**
   * List of dependencies of the library being prelinked.  This will be output
   * to [LinkedLibrary.dependencies].
   */
  final List<LinkedDependencyBuilder> dependencies =
      <LinkedDependencyBuilder>[];

  /**
   * Map from the absolute URI of a dependent library to the index of the
   * corresponding entry in [dependencies].
   */
  final Map<String, int> uriToDependency = <String, int>{};

  /**
   * List of public namespaces corresponding to each entry in [dependencies].
   */
  final List<_Namespace> dependencyToPublicNamespace = <_Namespace>[];

  /**
   * Map from absolute URI of a library to its export namespace.
   */
  final Map<String, _ExportNamespace> exportNamespaces = {};

  _Prelinker(this.definingUnitUri, this.definingUnit, this.getPart,
      this.getImport, this.declaredVariables) {
    partCache[definingUnitUri] = definingUnit;
    importCache[definingUnitUri] = definingUnit.publicNamespace;
  }

  void addClassToPrivateNamespace(int unitNum, UnlinkedClass cls) {
    _Namespace namespace = new _Namespace();
    cls.fields.forEach((field) {
      if (field.isStatic && field.isConst) {
        namespace.add(field.name,
            new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
      }
    });
    cls.executables.forEach((executable) {
      ReferenceKind kind = null;
      if (executable.kind == UnlinkedExecutableKind.constructor) {
        kind = ReferenceKind.constructor;
      } else if (executable.kind == UnlinkedExecutableKind.functionOrMethod &&
          executable.isStatic) {
        kind = ReferenceKind.method;
      } else if (executable.kind == UnlinkedExecutableKind.getter &&
          executable.isStatic) {
        kind = ReferenceKind.propertyAccessor;
      }
      if (kind != null && executable.name.isNotEmpty) {
        namespace.add(executable.name,
            new _Meaning(unitNum, kind, 0, executable.typeParameters.length));
      }
    });
    privateNamespace.add(cls.name,
        new _ClassMeaning(unitNum, 0, cls.typeParameters.length, namespace));
  }

  /**
   * Compute the public namespace for the library whose URI is reachable from
   * [definingUnit] via [absoluteUri], by aggregating together public namespace
   * information from all of its parts.
   */
  _Namespace aggregatePublicNamespace(String absoluteUri) {
    if (uriToDependency.containsKey(absoluteUri)) {
      return dependencyToPublicNamespace[uriToDependency[absoluteUri]];
    }
    assert(dependencies.length == dependencyToPublicNamespace.length);
    int dependency = dependencies.length;
    uriToDependency[absoluteUri] = dependency;
    List<String> unitUris = getUnitUris(absoluteUri);
    LinkedDependencyBuilder linkedDependency = new LinkedDependencyBuilder(
        uri: absoluteUri,
        parts: unitUris.skip(1).map((uri) => uri ?? '').toList());
    dependencies.add(linkedDependency);

    _Namespace aggregated = new _Namespace();

    for (int unitNum = 0; unitNum < unitUris.length; unitNum++) {
      String unitUri = unitUris[unitNum];
      UnlinkedPublicNamespace importedNamespace = getImportCached(unitUri);
      if (importedNamespace == null) {
        continue;
      }
      for (UnlinkedPublicName name in importedNamespace.names) {
        if (name.kind == ReferenceKind.classOrEnum) {
          _Namespace namespace = new _Namespace();
          name.members.forEach((executable) {
            namespace.add(
                executable.name,
                new _Meaning(
                    unitNum, executable.kind, 0, executable.numTypeParameters));
          });
          aggregated.add(
              name.name,
              new _ClassMeaning(
                  unitNum, dependency, name.numTypeParameters, namespace));
        } else {
          aggregated.add(
              name.name,
              new _Meaning(
                  unitNum, name.kind, dependency, name.numTypeParameters));
        }
      }
    }

    aggregated.rememberLibraryNames();

    dependencyToPublicNamespace.add(aggregated);
    return aggregated;
  }

  /**
   * Compute the export namespace for the library whose URI is reachable from
   * [definingUnit] via [absoluteUri], by aggregating together public namespace
   * information from the library and the transitive closure of its exports.
   */
  _Namespace computeExportNamespace(String absoluteUri) {
    int firstCycleIdOfLastCall = 0;
    _Namespace chaseExports(String absoluteUri) {
      _ExportNamespace exportNamespace = getExportNamespace(absoluteUri);

      // If the export namespace is ready, return it.
      if (exportNamespace.isFull) {
        firstCycleIdOfLastCall = 0;
        return exportNamespace.namespace;
      }

      // If we are computing the export namespace for this library, and we
      // reached here, then we found a cycle.
      if (exportNamespace.id != 0) {
        firstCycleIdOfLastCall = exportNamespace.id;
        return null;
      }

      // Give each library a unique identifier.
      exportNamespace.id = _ExportNamespace.nextId++;

      // Append from exports.
      int firstCycleId = 0;
      UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
      if (publicNamespace != null) {
        for (UnlinkedExportPublic export in publicNamespace.exports) {
          String unlinkedExportUri =
              _selectUri(export.uri, export.configurations);
          String exportUri = resolveUri(absoluteUri, unlinkedExportUri);
          if (exportUri != null) {
            NameFilter filter =
                new NameFilter.forUnlinkedCombinators(export.combinators);
            _Namespace exported = chaseExports(exportUri);
            exported?.forEach((String name, _Meaning meaning) {
              if (filter.accepts(name) &&
                  !exportNamespace.namespace.definesLibraryName(name)) {
                exportNamespace.namespace.add(name, meaning);
              }
            });
            if (firstCycleIdOfLastCall != 0) {
              if (firstCycleId == 0 || firstCycleId > firstCycleIdOfLastCall) {
                firstCycleId = firstCycleIdOfLastCall;
              }
            }
          }
        }
      }

      // If this library is the first component of the cycle, then we are at
      // the beginning of this cycle, and combination of partial export
      // namespaces of other exported libraries and declarations of this
      // library is the full export namespace of this library.
      if (firstCycleId != 0 && firstCycleId == exportNamespace.id) {
        firstCycleId = 0;
      }

      // We're done with this library, successfully or not.
      exportNamespace.id = 0;

      // If no cycle detected in exports, mark the export namespace as full.
      if (firstCycleId == 0) {
        exportNamespace.isFull = true;
      }

      // Return the full or partial result.
      firstCycleIdOfLastCall = firstCycleId;
      return exportNamespace.namespace;
    }

    _ExportNamespace.nextId = 1;
    return chaseExports(absoluteUri);
  }

  /**
   * Extract all the names defined in [unit] (which is the [unitNum]th unit in
   * the library being prelinked) and store them in [privateNamespace].
   * Excludes names introduced by `import` statements.
   */
  void extractPrivateNames(UnlinkedUnit unit, int unitNum) {
    for (UnlinkedClass cls in unit.classes) {
      addClassToPrivateNamespace(unitNum, cls);
    }
    for (UnlinkedEnum enm in unit.enums) {
      _Namespace namespace = new _Namespace();
      enm.values.forEach((UnlinkedEnumValue value) {
        namespace.add(value.name,
            new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
      });
      namespace.add('values',
          new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0));
      privateNamespace.add(
          enm.name, new _ClassMeaning(unitNum, 0, 0, namespace));
    }
    for (UnlinkedExecutable executable in unit.executables) {
      privateNamespace.add(
          executable.name,
          new _Meaning(
              unitNum,
              executable.kind == UnlinkedExecutableKind.functionOrMethod
                  ? ReferenceKind.topLevelFunction
                  : ReferenceKind.topLevelPropertyAccessor,
              0,
              executable.typeParameters.length));
    }
    for (UnlinkedClass mixin in unit.mixins) {
      addClassToPrivateNamespace(unitNum, mixin);
    }
    for (UnlinkedTypedef typedef in unit.typedefs) {
      ReferenceKind kind;
      switch (typedef.style) {
        case TypedefStyle.functionType:
          kind = ReferenceKind.typedef;
          break;
        case TypedefStyle.genericFunctionType:
          kind = ReferenceKind.genericFunctionTypedef;
          break;
      }
      assert(kind != null);
      privateNamespace.add(typedef.name,
          new _Meaning(unitNum, kind, 0, typedef.typeParameters.length));
    }
    for (UnlinkedVariable variable in unit.variables) {
      privateNamespace.add(variable.name,
          new _Meaning(unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
      if (!(variable.isConst || variable.isFinal)) {
        privateNamespace.add(
            variable.name + '=',
            new _Meaning(
                unitNum, ReferenceKind.topLevelPropertyAccessor, 0, 0));
      }
    }
  }

  /**
   * Filter the export namespace for the library whose URI is reachable the
   * given [absoluteUri], retaining only those names accepted by
   * [combinators], and store the resulting names in [result].  Names that
   * already exist in [result] are not overwritten.
   */
  void filterExportNamespace(String absoluteUri,
      List<UnlinkedCombinator> combinators, _Namespace result) {
    _Namespace exportNamespace = computeExportNamespace(absoluteUri);
    if (result == null) {
      // This can happen if the import prefix was shadowed by a local name, so
      // the imported symbols are inaccessible.
      return;
    }
    NameFilter filter = new NameFilter.forUnlinkedCombinators(combinators);
    exportNamespace.forEach((String name, _Meaning meaning) {
      if (filter.accepts(name) && !result.definesLibraryName(name)) {
        result.add(name, meaning);
      }
    });
  }

  /**
   * Return the [_ExportNamespace] for the library with the given [absoluteUri].
   * The export namespace might be full (will all exports included), or
   * partial (with public namespace, and only some of the exports included).
   */
  _ExportNamespace getExportNamespace(String absoluteUri) {
    _ExportNamespace exportNamespace = exportNamespaces[absoluteUri];
    if (exportNamespace == null) {
      _Namespace publicNamespace = aggregatePublicNamespace(absoluteUri);
      exportNamespace = new _ExportNamespace(publicNamespace);
      exportNamespaces[absoluteUri] = exportNamespace;
    }
    return exportNamespace;
  }

  /**
   * Wrapper around [getImport] that caches the return value in [importCache].
   */
  UnlinkedPublicNamespace getImportCached(String absoluteUri) {
    return importCache.putIfAbsent(absoluteUri, () => getImport(absoluteUri));
  }

  /**
   * Wrapper around [getPart] that caches the return value in [partCache] and
   * updates [importCache] appropriately.
   */
  UnlinkedUnit getPartCached(String absoluteUri) {
    return partCache.putIfAbsent(absoluteUri, () {
      UnlinkedUnit unit = getPart(absoluteUri);
      importCache[absoluteUri] = unit?.publicNamespace;
      return unit;
    });
  }

  /**
   * Compute the set of absolute URIs of all the compilation units in the
   * library whose URI is reachable from [definingUnit] via [absoluteUri].
   */
  List<String> getUnitUris(String absoluteUri) {
    List<String> result = <String>[absoluteUri];
    UnlinkedPublicNamespace publicNamespace = getImportCached(absoluteUri);
    if (publicNamespace != null) {
      result.addAll(publicNamespace.parts.map((String uri) {
        return resolveUri(absoluteUri, uri);
      }));
    }
    return result;
  }

  /**
   * Process a single `import` declaration in the library being prelinked.  The
   * return value is the index of the imported library in [dependencies].
   */
  int handleImport(UnlinkedImport import) {
    String unlinkedUri = import.isImplicit
        ? 'dart:core'
        : _selectUri(import.uri, import.configurations);
    String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);

    _Namespace targetNamespace = null;
    if (import.prefixReference != 0) {
      // The name introduced by an import declaration can't have a prefix of
      // its own.
      assert(
          definingUnit.references[import.prefixReference].prefixReference == 0);
      String prefix = definingUnit.references[import.prefixReference].name;
      _Meaning prefixMeaning = privateNamespace[prefix];
      if (prefixMeaning is _PrefixMeaning) {
        targetNamespace = prefixMeaning.namespace;
      }
    } else {
      targetNamespace = privateNamespace;
    }
    filterExportNamespace(absoluteUri, import.combinators, targetNamespace);
    return uriToDependency[absoluteUri];
  }

  /**
   * Produce a [LinkedUnit] for the given [unit], by resolving every one of
   * its references.
   */
  LinkedUnitBuilder linkUnit(UnlinkedUnit unit) {
    if (unit == null) {
      return new LinkedUnitBuilder();
    }
    Map<int, _Namespace> prefixNamespaces = <int, _Namespace>{};
    List<LinkedReferenceBuilder> references = <LinkedReferenceBuilder>[];
    for (int i = 0; i < unit.references.length; i++) {
      UnlinkedReference reference = unit.references[i];
      _Namespace namespace;
      if (reference.prefixReference == 0) {
        namespace = privateNamespace;
      } else {
        // Prefix references must always point backward.
        assert(reference.prefixReference < i);
        namespace = prefixNamespaces[reference.prefixReference];
        // Expressions like 'a.b.c.d' cannot be prelinked.
        namespace ??= new _Namespace();
      }
      _Meaning meaning = namespace[reference.name];
      if (meaning != null) {
        if (meaning is _PrefixMeaning) {
          prefixNamespaces[i] = meaning.namespace;
        } else if (meaning is _ClassMeaning) {
          prefixNamespaces[i] = meaning.namespace;
        }
        references.add(meaning.encodeReference());
      } else {
        references
            .add(new LinkedReferenceBuilder(kind: ReferenceKind.unresolved));
      }
    }
    return new LinkedUnitBuilder(references: references);
  }

  /**
   * Form the [LinkedLibrary] for the [definingUnit] that was passed to the
   * constructor.
   */
  LinkedLibraryBuilder prelink() {
    aggregatePublicNamespace(definingUnitUri);

    // Gather up the unlinked summaries for all the compilation units in the
    // library.
    List<String> unitUris = getUnitUris(definingUnitUri);
    List<UnlinkedUnit> units = unitUris.map(getPartCached).toList();

    // Create the private namespace for the library by gathering all the names
    // defined in its compilation units.
    for (int unitNum = 0; unitNum < units.length; unitNum++) {
      UnlinkedUnit unit = units[unitNum];
      if (unit != null) {
        extractPrivateNames(unit, unitNum);
      }
    }

    // Fill in exported names.  This must be done before filling in prefixes
    // defined in import declarations, because prefixes shouldn't shadow
    // exports.
    List<LinkedExportNameBuilder> exportNames = <LinkedExportNameBuilder>[];
    computeExportNamespace(definingUnitUri)
        .forEach((String name, _Meaning meaning) {
      if (!privateNamespace.definesName(name)) {
        exportNames.add(meaning.encodeExportName(name));
      }
    });

    // Fill in prefixes defined in import declarations.
    for (UnlinkedImport import in units[0].imports) {
      if (import.prefixReference != 0) {
        String name = units[0].references[import.prefixReference].name;
        if (!privateNamespace.definesName(name)) {
          privateNamespace.add(name, new _PrefixMeaning());
        }
      }
    }

    // All the names defined so far are library local, they take precedence
    // over anything imported from other libraries.
    privateNamespace.rememberLibraryNames();

    // Fill in imported and exported names.
    List<int> importDependencies =
        definingUnit.imports.map(handleImport).toList();
    List<int> exportDependencies = definingUnit.publicNamespace.exports
        .map((UnlinkedExportPublic exp) {
          String unlinkedUri = _selectUri(exp.uri, exp.configurations);
          String absoluteUri = resolveUri(definingUnitUri, unlinkedUri);
          return uriToDependency[absoluteUri];
        })
        .where((dependency) => dependency != null)
        .toList();

    // Link each compilation unit.
    List<LinkedUnitBuilder> linkedUnits = units.map(linkUnit).toList();

    return new LinkedLibraryBuilder(
        units: linkedUnits,
        dependencies: dependencies,
        importDependencies: importDependencies,
        exportDependencies: exportDependencies,
        exportNames: exportNames,
        numPrelinkedDependencies: dependencies.length);
  }

  /**
   * Resolve [relativeUri] relative to [containingUri].  Return `null` if
   * [relativeUri] is invalid or empty, so cannot be resolved.
   */
  String resolveUri(String containingUri, String relativeUri) {
    if (relativeUri == '') {
      return null;
    }
    try {
      Uri containingUriObj = Uri.parse(containingUri);
      Uri relativeUriObj = Uri.parse(relativeUri);
      return resolveRelativeUri(containingUriObj, relativeUriObj).toString();
    } on FormatException {
      return null;
    }
  }

  /**
   * Return the URI of the first configuration from the given [configurations]
   * which condition is satisfied, or the [defaultUri].
   */
  String _selectUri(
      String defaultUri, List<UnlinkedConfiguration> configurations) {
    for (UnlinkedConfiguration configuration in configurations) {
      if (declaredVariables.get(configuration.name) == configuration.value) {
        return configuration.uri;
      }
    }
    return defaultUri;
  }
}
