// Copyright (c) 2014, 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.

// Test that the additional runtime type support is output to the right
// Files when using deferred loading.

import 'package:compiler/compiler_new.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/constants/values.dart';
import 'package:compiler/src/deferred_load.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/util/util.dart';
import 'package:expect/expect.dart';
import '../helpers/memory_compiler.dart';
import '../helpers/output_collector.dart';
import '../helpers/program_lookup.dart';

class OutputUnitDescriptor {
  final String uri;
  final String member;
  final String name;

  const OutputUnitDescriptor(this.uri, this.member, this.name);
}

run(Map<String, String> sourceFiles, List<OutputUnitDescriptor> outputUnits,
    Map<String, Set<String>> expectedOutputUnits,
    {bool useCFEConstants: false}) async {
  OutputCollector collector = new OutputCollector();
  CompilationResult result = await runCompiler(
      memorySourceFiles: sourceFiles,
      outputProvider: collector,
      options: useCFEConstants
          ? ['${Flags.enableLanguageExperiments}=constant-update-2018']
          : ['${Flags.enableLanguageExperiments}=no-constant-update-2018']);
  Compiler compiler = result.compiler;
  ProgramLookup lookup = new ProgramLookup(compiler.backendStrategy);
  var closedWorld = compiler.backendClosedWorldForTesting;
  var elementEnvironment = closedWorld.elementEnvironment;

  LibraryEntity lookupLibrary(name) {
    return elementEnvironment.lookupLibrary(Uri.parse(name));
  }

  OutputUnit Function(MemberEntity) outputUnitForMember =
      closedWorld.outputUnitData.outputUnitForMember;

  Map<String, Fragment> fragments = {};
  fragments['main'] = lookup.program.mainFragment;

  for (OutputUnitDescriptor descriptor in outputUnits) {
    LibraryEntity library = lookupLibrary(descriptor.uri);
    MemberEntity member =
        elementEnvironment.lookupLibraryMember(library, descriptor.member);
    OutputUnit outputUnit = outputUnitForMember(member);
    fragments[descriptor.name] = lookup.getFragment(outputUnit);
  }

  Map<String, Set<String>> actualOutputUnits = {};

  bool errorsFound = false;

  void processFragment(String fragmentName, Fragment fragment) {
    for (Constant constant in fragment.constants) {
      String text = constant.value.toStructuredText();
      Set<String> expectedConstantUnit = expectedOutputUnits[text];
      if (expectedConstantUnit == null) {
        if (constant.value is DeferredGlobalConstantValue) {
          print('ERROR: No expectancy for $constant found in $fragmentName');
          errorsFound = true;
        }
      } else {
        (actualOutputUnits[text] ??= <String>{}).add(fragmentName);
      }
    }
  }

  fragments.forEach(processFragment);

  expectedOutputUnits.forEach((String constant, Set<String> expectedSet) {
    Set<String> actualSet = actualOutputUnits[constant] ?? const <String>{};
    if (!equalSets(expectedSet, actualSet)) {
      print("ERROR: Constant $constant found in $actualSet, expected "
          "$expectedSet");
      errorsFound = true;
    }
  });

  Expect.isFalse(errorsFound, "Errors found.");
}
