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

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';
import 'package:front_end/src/base/source.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)
      : super(context, 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 SummaryDataStore _dataStore;

  StoreBasedSummaryResynthesizer _resynthesizer;

  ResynthesizerResultProvider(this.context, 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, TargetedResult.EMPTY_LIST);
      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,
              TargetedResult.EMPTY_LIST);
          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, TargetedResult.EMPTY_LIST);
      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, TargetedResult.EMPTY_LIST);
        return true;
      } else if (result == READY_LIBRARY_ELEMENT2 ||
          result == READY_LIBRARY_ELEMENT6 ||
          result == READY_LIBRARY_ELEMENT7) {
        entry.setValue(
            result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
        return true;
      } else if (result == MODIFICATION_TIME) {
        entry.setValue(
            result as ResultDescriptor<int>, 0, TargetedResult.EMPTY_LIST);
        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,
              TargetedResult.EMPTY_LIST);
          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, TargetedResult.EMPTY_LIST);
          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, TargetedResult.EMPTY_LIST);
        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, TargetedResult.EMPTY_LIST);
          return true;
        }
      }
    } else if (target is VariableElement) {
      if (result == INFERRED_STATIC_VARIABLE) {
        entry.setValue(result as ResultDescriptor<VariableElement>, target,
            TargetedResult.EMPTY_LIST);
        return true;
      }
    }
    // Unknown target.
    return false;
  }

  /**
   * Create the [resynthesizer] instance.
   *
   * Subclasses must call this method in their constructors.
   */
  void createResynthesizer() {
    _resynthesizer = new StoreBasedSummaryResynthesizer(context,
        context.sourceFactory, context.analysisOptions.strongMode, _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,
      SourceFactory sourceFactory, bool strongMode, this._dataStore)
      : super(context, sourceFactory, strongMode);

  @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);
  }
}
