import 'dart:io' as io;
import 'dart:math' show min;

import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/general.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';

/**
 * A [ConflictingSummaryException] indicates that two different summaries
 * provided to a [SummaryDataStore] conflict.
 */
class ConflictingSummaryException implements Exception {
  final String duplicatedUri;
  final String summary1Uri;
  final String summary2Uri;
  String _message;

  ConflictingSummaryException(Iterable<String> summaryPaths, this.duplicatedUri,
      this.summary1Uri, this.summary2Uri) {
    // Paths are often quite long.  Find and extract out a common prefix to
    // build a more readable error message.
    var prefix = _commonPrefix(summaryPaths.toList());
    _message = '''
These summaries conflict because they overlap:
- ${summary1Uri.substring(prefix)}
- ${summary2Uri.substring(prefix)}
Both contain the file: $duplicatedUri.
This typically indicates an invalid build rule where two or more targets
include the same source.
  ''';
  }

  String toString() => _message;

  /// Given a set of file paths, find a common prefix.
  int _commonPrefix(List<String> strings) {
    if (strings.isEmpty) return 0;
    var first = strings.first;
    int common = first.length;
    for (int i = 1; i < strings.length; ++i) {
      var current = strings[i];
      common = min(common, current.length);
      for (int j = 0; j < common; ++j) {
        if (first[j] != current[j]) {
          common = j;
          if (common == 0) return 0;
          break;
        }
      }
    }
    // The prefix should end with a file separator.
    var last =
        first.substring(0, common).lastIndexOf(io.Platform.pathSeparator);
    return last < 0 ? 0 : last + 1;
  }
}

/**
 * The [ResultProvider] that provides results from input package summaries.
 */
class InputPackagesResultProvider extends ResynthesizerResultProvider {
  InputPackagesResultProvider(
      InternalAnalysisContext context, SummaryDataStore dataStore,
      {AnalysisSession session})
      : super(context, session, dataStore) {
    createResynthesizer();
    context.typeProvider = resynthesizer.typeProvider;
    resynthesizer.finishCoreAsyncLibraries();
  }

  @override
  bool hasResultsForSource(Source source) {
    String uriString = source.uri.toString();
    return resynthesizer.hasLibrarySummary(uriString);
  }
}

/**
 * The [UriResolver] that knows about sources that are served from their
 * summaries.
 */
@deprecated
class InSummaryPackageUriResolver extends UriResolver {
  final SummaryDataStore _dataStore;

  InSummaryPackageUriResolver(this._dataStore);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    actualUri ??= uri;
    String uriString = uri.toString();
    UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
    if (unit != null) {
      String summaryPath = _dataStore.uriToSummaryPath[uriString];
      return new InSummarySource(actualUri, summaryPath);
    }
    return null;
  }
}

/**
 * A placeholder of a source that is part of a package whose analysis results
 * are served from its summary.  This source uses its URI as [fullName] and has
 * empty contents.
 */
class InSummarySource extends BasicSource {
  /**
   * The summary file where this source was defined.
   */
  final String summaryPath;

  InSummarySource(Uri uri, this.summaryPath) : super(uri);

  @override
  TimestampedData<String> get contents => new TimestampedData<String>(0, '');

  @override
  int get modificationStamp => 0;

  @override
  UriKind get uriKind => UriKind.PACKAGE_URI;

  @override
  bool exists() => true;

  @override
  String toString() => uri.toString();
}

/**
 * The [UriResolver] that knows about sources that are served from their
 * summaries.
 */
class InSummaryUriResolver extends UriResolver {
  ResourceProvider resourceProvider;
  final SummaryDataStore _dataStore;

  InSummaryUriResolver(this.resourceProvider, this._dataStore);

  @override
  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
    actualUri ??= uri;
    String uriString = uri.toString();
    UnlinkedUnit unit = _dataStore.unlinkedMap[uriString];
    if (unit != null) {
      String summaryPath = _dataStore.uriToSummaryPath[uriString];
      return new InSummarySource(actualUri, summaryPath);
    }
    return null;
  }
}

/**
 * The [ResultProvider] that provides results using summary resynthesizer.
 */
abstract class ResynthesizerResultProvider extends ResultProvider {
  final InternalAnalysisContext context;
  final AnalysisSession session;
  final SummaryDataStore _dataStore;

  StoreBasedSummaryResynthesizer _resynthesizer;

  ResynthesizerResultProvider(this.context, this.session, this._dataStore);

  SummaryResynthesizer get resynthesizer => _resynthesizer;

  /**
   * Add a new [bundle] to the resynthesizer.
   */
  void addBundle(String path, PackageBundle bundle) {
    _dataStore.addBundle(path, bundle);
  }

  @override
  bool compute(CacheEntry entry, ResultDescriptor result) {
    AnalysisTarget target = entry.target;

    if (result == TYPE_PROVIDER) {
      entry.setValue(result as ResultDescriptor<TypeProvider>,
          _resynthesizer.typeProvider, const <TargetedResult>[]);
      return true;
    }

    // LINE_INFO can be provided using just the UnlinkedUnit.
    if (target is Source && result == LINE_INFO) {
      String uriString = target.uri.toString();
      UnlinkedUnit unlinkedUnit = _dataStore.unlinkedMap[uriString];
      if (unlinkedUnit != null) {
        List<int> lineStarts = unlinkedUnit.lineStarts;
        if (lineStarts.isNotEmpty) {
          LineInfo lineInfo = new LineInfo(lineStarts);
          entry.setValue(result as ResultDescriptor<LineInfo>, lineInfo,
              const <TargetedResult>[]);
          return true;
        }
      }
      return false;
    }

    // Check whether there are results for the source.
    if (!hasResultsForSource(target.librarySource ?? target.source)) {
      return false;
    }
    // Constant expressions are always resolved in summaries.
    if (result == CONSTANT_EXPRESSION_RESOLVED &&
        target is ConstantEvaluationTarget) {
      entry.setValue(
          result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
      return true;
    }
    // Provide results for Source.
    if (target is Source) {
      String uriString = target.uri.toString();
      // Provide known results.
      if (result == LIBRARY_ELEMENT1 ||
          result == LIBRARY_ELEMENT2 ||
          result == LIBRARY_ELEMENT3 ||
          result == LIBRARY_ELEMENT4 ||
          result == LIBRARY_ELEMENT5 ||
          result == LIBRARY_ELEMENT6 ||
          result == LIBRARY_ELEMENT7 ||
          result == LIBRARY_ELEMENT8 ||
          result == LIBRARY_ELEMENT9 ||
          result == LIBRARY_ELEMENT) {
        LibraryElement libraryElement =
            resynthesizer.getLibraryElement(uriString);
        entry.setValue(result as ResultDescriptor<LibraryElement>,
            libraryElement, const <TargetedResult>[]);
        return true;
      } else if (result == READY_LIBRARY_ELEMENT2 ||
          result == READY_LIBRARY_ELEMENT6 ||
          result == READY_LIBRARY_ELEMENT7) {
        entry.setValue(
            result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
        return true;
      } else if (result == MODIFICATION_TIME) {
        entry.setValue(
            result as ResultDescriptor<int>, 0, const <TargetedResult>[]);
        return true;
      } else if (result == SOURCE_KIND) {
        UnlinkedUnit unlinked = _dataStore.unlinkedMap[uriString];
        if (unlinked != null) {
          entry.setValue(
              result as ResultDescriptor<SourceKind>,
              unlinked.isPartOf ? SourceKind.PART : SourceKind.LIBRARY,
              const <TargetedResult>[]);
          return true;
        }
        return false;
      } else if (result == CONTAINING_LIBRARIES) {
        List<String> libraryUriStrings =
            _dataStore.getContainingLibraryUris(uriString);
        if (libraryUriStrings != null) {
          List<Source> librarySources = libraryUriStrings
              .map((libraryUriString) =>
                  context.sourceFactory.resolveUri(target, libraryUriString))
              .toList(growable: false);
          entry.setValue(result as ResultDescriptor<List<Source>>,
              librarySources, const <TargetedResult>[]);
          return true;
        }
        return false;
      }
    } else if (target is LibrarySpecificUnit) {
      if (result == CREATED_RESOLVED_UNIT1 ||
          result == CREATED_RESOLVED_UNIT2 ||
          result == CREATED_RESOLVED_UNIT3 ||
          result == CREATED_RESOLVED_UNIT4 ||
          result == CREATED_RESOLVED_UNIT5 ||
          result == CREATED_RESOLVED_UNIT6 ||
          result == CREATED_RESOLVED_UNIT7 ||
          result == CREATED_RESOLVED_UNIT8 ||
          result == CREATED_RESOLVED_UNIT9 ||
          result == CREATED_RESOLVED_UNIT10 ||
          result == CREATED_RESOLVED_UNIT11) {
        entry.setValue(
            result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
        return true;
      }
      if (result == COMPILATION_UNIT_ELEMENT) {
        String libraryUri = target.library.uri.toString();
        String unitUri = target.unit.uri.toString();
        CompilationUnitElement unit = resynthesizer.getElement(
            new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
        if (unit != null) {
          entry.setValue(result as ResultDescriptor<CompilationUnitElement>,
              unit, const <TargetedResult>[]);
          return true;
        }
      }
    } else if (target is VariableElement) {
      if (result == INFERRED_STATIC_VARIABLE) {
        entry.setValue(result as ResultDescriptor<VariableElement>, target,
            const <TargetedResult>[]);
        return true;
      }
    }
    // Unknown target.
    return false;
  }

  /**
   * Create the [resynthesizer] instance.
   *
   * Subclasses must call this method in their constructors.
   */
  void createResynthesizer() {
    _resynthesizer = new StoreBasedSummaryResynthesizer(
        context, session, context.sourceFactory, true, _dataStore);
  }

  /**
   * Return `true` if this result provider can provide a result for the
   * given [source].  The provider must ensure that [addBundle] is invoked for
   * every bundle that would be required to provide results for the [source].
   */
  bool hasResultsForSource(Source source);
}

/**
 * A concrete resynthesizer that serves summaries from [SummaryDataStore].
 */
class StoreBasedSummaryResynthesizer extends SummaryResynthesizer {
  final SummaryDataStore _dataStore;

  StoreBasedSummaryResynthesizer(
      AnalysisContext context,
      AnalysisSession session,
      SourceFactory sourceFactory,
      bool _,
      this._dataStore)
      : super(context, session, sourceFactory, true);

  @override
  LinkedLibrary getLinkedSummary(String uri) {
    return _dataStore.linkedMap[uri];
  }

  @override
  UnlinkedUnit getUnlinkedSummary(String uri) {
    return _dataStore.unlinkedMap[uri];
  }

  @override
  bool hasLibrarySummary(String uri) {
    LinkedLibrary linkedLibrary = _dataStore.linkedMap[uri];
    return linkedLibrary != null;
  }
}

/**
 * A [SummaryDataStore] is a container for the data extracted from a set of
 * summary package bundles.  It contains maps which can be used to find linked
 * and unlinked summaries by URI.
 */
class SummaryDataStore {
  /**
   * List of all [PackageBundle]s.
   */
  final List<PackageBundle> bundles = <PackageBundle>[];

  /**
   * Map from the URI of a compilation unit to the unlinked summary of that
   * compilation unit.
   */
  final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};

  /**
   * Map from the URI of a library to the linked summary of that library.
   */
  final Map<String, LinkedLibrary> linkedMap = <String, LinkedLibrary>{};

  /**
   * Map from the URI of a library to the summary path that contained it.
   */
  final Map<String, String> uriToSummaryPath = <String, String>{};

  /**
   * List of summary paths.
   */
  final Iterable<String> _summaryPaths;

  /**
   * If true, do not accept multiple summaries that contain the same Dart uri.
   */
  bool _disallowOverlappingSummaries;

  /**
   * Create a [SummaryDataStore] and populate it with the summaries in
   * [summaryPaths].
   */
  SummaryDataStore(Iterable<String> summaryPaths,
      {bool disallowOverlappingSummaries: false,
      ResourceProvider resourceProvider})
      : _summaryPaths = summaryPaths,
        _disallowOverlappingSummaries = disallowOverlappingSummaries {
    summaryPaths.forEach((String path) => _fillMaps(path, resourceProvider));
  }

  /**
   * Add the given [bundle] loaded from the file with the given [path].
   */
  void addBundle(String path, PackageBundle bundle) {
    bundles.add(bundle);
    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
      String uri = bundle.unlinkedUnitUris[i];
      if (_disallowOverlappingSummaries &&
          uriToSummaryPath.containsKey(uri) &&
          (uriToSummaryPath[uri] != path)) {
        throw new ConflictingSummaryException(
            _summaryPaths, uri, uriToSummaryPath[uri], path);
      }
      uriToSummaryPath[uri] = path;
      addUnlinkedUnit(uri, bundle.unlinkedUnits[i]);
    }
    for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
      String uri = bundle.linkedLibraryUris[i];
      addLinkedLibrary(uri, bundle.linkedLibraries[i]);
    }
  }

  /**
   * Add the given [linkedLibrary] with the given [uri].
   */
  void addLinkedLibrary(String uri, LinkedLibrary linkedLibrary) {
    linkedMap[uri] = linkedLibrary;
  }

  /**
   * Add into this store the unlinked units and linked libraries of [other].
   */
  void addStore(SummaryDataStore other) {
    unlinkedMap.addAll(other.unlinkedMap);
    linkedMap.addAll(other.linkedMap);
  }

  /**
   * Add the given [unlinkedUnit] with the given [uri].
   */
  void addUnlinkedUnit(String uri, UnlinkedUnit unlinkedUnit) {
    unlinkedMap[uri] = unlinkedUnit;
  }

  /**
   * Return a list of absolute URIs of the libraries that contain the unit with
   * the given [unitUriString], or `null` if no such library is in the store.
   */
  List<String> getContainingLibraryUris(String unitUriString) {
    // The unit is the defining unit of a library.
    if (linkedMap.containsKey(unitUriString)) {
      return <String>[unitUriString];
    }
    // Check every unlinked unit whether it uses [unitUri] as a part.
    List<String> libraryUriStrings = <String>[];
    unlinkedMap.forEach((unlinkedUnitUriString, unlinkedUnit) {
      Uri libraryUri = Uri.parse(unlinkedUnitUriString);
      for (String partUriString in unlinkedUnit.publicNamespace.parts) {
        Uri partUri = Uri.parse(partUriString);
        String partAbsoluteUriString =
            resolveRelativeUri(libraryUri, partUri).toString();
        if (partAbsoluteUriString == unitUriString) {
          libraryUriStrings.add(unlinkedUnitUriString);
        }
      }
    });
    return libraryUriStrings.isNotEmpty ? libraryUriStrings : null;
  }

  /**
   * Return `true` if the store contains the linked summary for the library
   * with the given absolute [uri].
   */
  bool hasLinkedLibrary(String uri) {
    return linkedMap.containsKey(uri);
  }

  /**
   * Return `true` if the store contains the unlinked summary for the unit
   * with the given absolute [uri].
   */
  bool hasUnlinkedUnit(String uri) {
    return unlinkedMap.containsKey(uri);
  }

  void _fillMaps(String path, ResourceProvider resourceProvider) {
    List<int> buffer;
    if (resourceProvider != null) {
      var file = resourceProvider.getFile(path);
      buffer = file.readAsBytesSync();
    } else {
      io.File file = new io.File(path);
      buffer = file.readAsBytesSync();
    }
    PackageBundle bundle = new PackageBundle.fromBuffer(buffer);
    addBundle(path, bundle);
  }
}
