// 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.

/// An implementation of [Pipeline] that runs in-memory.
///
/// To define a step, implement [MemoryModularStep].
import 'pipeline.dart';
import 'suite.dart';

/// A hook to fetch data previously computed for a dependency.
typedef ModuleDataProvider = Object? Function(Module, DataId);
typedef SourceProvider = String? Function(Uri);

abstract class MemoryModularStep extends ModularStep {
  Future<Map<DataId, Object>> execute(
      Module module,
      SourceProvider sourceProvider,
      ModuleDataProvider dataProvider,
      List<String> flags);
}

class MemoryPipeline extends Pipeline<MemoryModularStep> {
  final Map<Uri, String> _sources;

  /// Internal state to hold the current results as they are computed by the
  /// pipeline. Expected to be null before and after the pipeline runs.
  Map<Module, Map<DataId, Object>>? _results;

  /// A copy of [_result] at the time the pipeline last finished running.
  Map<Module, Map<DataId, Object>>? resultsForTesting;

  final ConfigurationRegistry? _registry;

  /// Cache of results when [cacheSharedModules] is true
  final List<Map<Module, Map<DataId, Object>>> _resultCache;

  MemoryPipeline(this._sources, List<MemoryModularStep> steps,
      {bool cacheSharedModules: false})
      : _registry = cacheSharedModules ? new ConfigurationRegistry() : null,
        _resultCache = cacheSharedModules ? [] : const [],
        super(steps, cacheSharedModules);

  @override
  Future<void> run(ModularTest test) async {
    var results = _results = {};
    Map<Module, Map<DataId, Object>>? cache = null;
    if (cacheSharedModules) {
      int id = _registry!.computeConfigurationId(test);
      if (id < _resultCache.length) {
        cache = _resultCache[id];
      } else {
        assert(id == _resultCache.length);
        _resultCache.add(cache = {});
      }
      results.addAll(cache);
    }
    await super.run(test);
    resultsForTesting = results;
    if (cacheSharedModules) {
      for (var module in results.keys) {
        if (module.isShared) {
          cache![module] = results[module]!;
        }
      }
    }
    _results = null;
  }

  @override
  Future<void> runStep(MemoryModularStep step, Module module,
      Map<Module, Set<DataId>> visibleData, List<String> flags) async {
    final results = _results!;
    if (cacheSharedModules && module.isShared) {
      bool allCachedResultsFound = true;
      for (var dataId in step.resultData) {
        if (results[module] == null || results[module]![dataId] == null) {
          allCachedResultsFound = false;
          break;
        }
      }
      if (allCachedResultsFound) {
        step.notifyCached(module);
        return;
      }
    }

    Map<Module, Map<DataId, Object>> inputData = {};
    visibleData.forEach((module, dataIdSet) {
      inputData[module] = {};
      for (var dataId in dataIdSet) {
        inputData[module]![dataId] = results[module]![dataId]!;
      }
    });
    Map<Uri, String> inputSources = {};
    if (step.needsSources) {
      module.sources.forEach((relativeUri) {
        var uri = module.rootUri.resolveUri(relativeUri);
        inputSources[uri] = _sources[uri]!;
      });
    }
    Map<DataId, Object> result = await step.execute(
        module,
        (Uri uri) => inputSources[uri],
        (Module m, DataId id) => inputData[m]![id],
        flags);
    for (var dataId in step.resultData) {
      (results[module] ??= {})[dataId] = result[dataId]!;
    }
  }
}
