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

/// Test that the dart2js copy of [KernelVisitor] generates the expected IR as
/// defined by kernel spec-mode test files.

import 'dart:io';
import 'dart:async';
import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend;
import 'package:compiler/src/commandline_options.dart' show Flags;
import 'package:kernel/ast.dart';
import 'package:kernel/text/ast_to_text.dart';
import 'package:kernel/transformations/mixin_full_resolution.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:path/path.dart' as pathlib;
import 'package:test/test.dart';

import '../memory_compiler.dart';

const String TESTCASE_DIR = 'pkg/front_end/testcases/';

const List<String> TESTS = const <String>[
  'DeltaBlue',
  'argument',
  'arithmetic',
  'async_function',
  'bad_store',
  'call',
  'closure',
  'covariant_generic',
  'escape',
  'fallthrough',
  'micro',
  'named_parameters',
  'null_aware',
  'optional',
  'override',
  'prefer_baseclass',
  'redirecting_factory',
  'static_setter',
  'store_load',
  'stringliteral',
  'uninitialized_fields',
  'unused_methods',
  'void-methods',
];

main(List<String> arguments) {
  if (arguments.isEmpty) {
    for (String testName in TESTS) {
      scheduleTest(testName, selected: false);
    }
  } else {
    for (String testName in arguments) {
      scheduleTest(testName, selected: true);
    }
  }
}

scheduleTest(String name, {bool selected}) async {
  test(name, () async {
    Uri uri = Uri.base.resolve(TESTCASE_DIR).resolve('$name.dart');
    var compiler = await newCompiler();
    await compiler.run(uri);
    var loadedLibraries = await compiler.libraryLoader.loadLibrary(uri);
    compiler.processLoadedLibraries(loadedLibraries);
    var library = loadedLibraries.rootLibrary;
    JavaScriptBackend backend = compiler.backend;
    StringBuffer buffer = new StringBuffer();
    Program program = backend.kernelTask.buildProgram(library);
    new MixinFullResolution().transform(program);
    new Printer(buffer).writeLibraryFile(program.mainMethod.enclosingLibrary);
    String actual = buffer.toString();
    String expected =
        new File('${TESTCASE_DIR}/$name.dart.direct.expect').readAsStringSync();
    if (selected) {
      String input = new File('${TESTCASE_DIR}/$name.dart').readAsStringSync();
      print('============================================================');
      print(name);
      print('--input-----------------------------------------------------');
      print(input);
      print('--expected--------------------------------------------------');
      print(expected);
      print('--actual----------------------------------------------------');
      print(actual);
    }
    expect(actual, equals(expected));
  });
}

Future<Compiler> newCompiler() async {
  var compiler = compilerFor(
      options: [Flags.analyzeOnly, Flags.analyzeAll, Flags.useKernel]);
  await compiler.setupSdk();

  // The visitor no longer enqueues elements that are not reachable from the
  // program. The mixin-full resolution transform run by the test expects to
  // find dart.core::Iterator.
  var loadedLibraries =
      await compiler.libraryLoader.loadLibrary(Uri.parse('dart:core'));
  compiler.processLoadedLibraries(loadedLibraries);
  var core = loadedLibraries.rootLibrary;
  compiler.startResolution();
  var cls = core.implementation.localLookup('Iterator');
  cls.ensureResolved(compiler.resolution);
  return compiler;
}
