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

import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/elements/entities.dart';
import 'package:compiler/src/world.dart';
import 'package:expect/expect.dart';
import '../memory_compiler.dart';

enum Kind {
  regular,
  native,
  jsInterop,
}

main() {
  asyncTest(() async {
    await runTest('tests/compiler/dart2js_extra/jsinterop_test.dart', '', {
      'Class': Kind.regular,
      'JsInteropClass': Kind.jsInterop,
      'topLevelField': Kind.regular,
      'topLevelGetter': Kind.regular,
      'topLevelSetter': Kind.regular,
      'topLevelFunction': Kind.regular,
      'externalTopLevelGetter': Kind.jsInterop,
      'externalTopLevelSetter': Kind.jsInterop,
      'externalTopLevelFunction': Kind.jsInterop,
      'externalTopLevelJsInteropGetter': Kind.jsInterop,
      'externalTopLevelJsInteropSetter': Kind.jsInterop,
      'externalTopLevelJsInteropFunction': Kind.jsInterop,
      'Class.generative': Kind.regular,
      'Class.fact': Kind.regular,
      'Class.instanceField': Kind.regular,
      'Class.instanceGetter': Kind.regular,
      'Class.instanceSetter': Kind.regular,
      'Class.instanceMethod': Kind.regular,
      'Class.staticField': Kind.regular,
      'Class.staticGetter': Kind.regular,
      'Class.staticSetter': Kind.regular,
      'Class.staticMethod': Kind.regular,
      'JsInteropClass.externalGenerative': Kind.jsInterop,
      'JsInteropClass.externalFact': Kind.jsInterop,
      'JsInteropClass.externalJsInteropGenerative': Kind.jsInterop,
      'JsInteropClass.externalJsInteropFact': Kind.jsInterop,
      'JsInteropClass.externalInstanceGetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceSetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceMethod': Kind.jsInterop,
      'JsInteropClass.externalStaticGetter': Kind.jsInterop,
      'JsInteropClass.externalStaticSetter': Kind.jsInterop,
      'JsInteropClass.externalStaticMethod': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropGetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropSetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropMethod': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropGetter': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropSetter': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropMethod': Kind.jsInterop,
    }, skipList: [
      // TODO(34174): Js-interop fields should not be allowed.
      '01',
      '02',
      '03',
      '04',
      '38',
      '42',
      '46',
      '51',
      // TODO(33834): Non-external constructors should not be allowed.
      '34',
      '35',
      '36',
      '37',
    ]);
    await runTest('tests/compiler/dart2js_extra/non_jsinterop_test.dart', '', {
      'Class': Kind.regular,
      'JsInteropClass': Kind.jsInterop,
      'topLevelField': Kind.regular,
      'topLevelGetter': Kind.regular,
      'topLevelSetter': Kind.regular,
      'topLevelFunction': Kind.regular,
      'externalTopLevelJsInteropGetter': Kind.jsInterop,
      'externalTopLevelJsInteropSetter': Kind.jsInterop,
      'externalTopLevelJsInteropFunction': Kind.jsInterop,
      'Class.generative': Kind.regular,
      'Class.fact': Kind.regular,
      'Class.instanceField': Kind.regular,
      'Class.instanceGetter': Kind.regular,
      'Class.instanceSetter': Kind.regular,
      'Class.instanceMethod': Kind.regular,
      'Class.staticField': Kind.regular,
      'Class.staticGetter': Kind.regular,
      'Class.staticSetter': Kind.regular,
      'Class.staticMethod': Kind.regular,
      'JsInteropClass.externalGenerative': Kind.jsInterop,
      'JsInteropClass.externalFact': Kind.jsInterop,
      'JsInteropClass.externalJsInteropGenerative': Kind.jsInterop,
      'JsInteropClass.externalJsInteropFact': Kind.jsInterop,
      'JsInteropClass.externalInstanceGetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceSetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceMethod': Kind.jsInterop,
      'JsInteropClass.externalStaticGetter': Kind.jsInterop,
      'JsInteropClass.externalStaticSetter': Kind.jsInterop,
      'JsInteropClass.externalStaticMethod': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropGetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropSetter': Kind.jsInterop,
      'JsInteropClass.externalInstanceJsInteropMethod': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropGetter': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropSetter': Kind.jsInterop,
      'JsInteropClass.externalStaticJsInteropMethod': Kind.jsInterop,
    }, skipList: [
      // TODO(34174): Js-interop fields should not be allowed.
      '01',
      '02',
      '03',
      '04',
      '38',
      '42',
      '46',
      '51',
      // TODO(33834): Non-external constructors should not be allowed.
      '34',
      '35',
      '36',
      '37',
    ]);
    // TODO(johnniwinther): Add similar test for native declarations.
  });
}

runTest(String fileName, String location, Map<String, Kind> expectations,
    {List<String> skipList: const <String>[]}) async {
  print('--------------------------------------------------------------------');
  print('Testing $fileName');
  print('--------------------------------------------------------------------');
  String test = new File(fileName).readAsStringSync();

  List<String> commonLines = <String>[];
  Map<String, SubTest> subTests = <String, SubTest>{};

  int lineIndex = 0;
  for (String line in test.split('\n')) {
    int index = line.indexOf('//#');
    if (index != -1) {
      String prefix = line.substring(0, index);
      String suffix = line.substring(index + 3);
      String name = suffix.substring(0, suffix.indexOf((':'))).trim();
      SubTest subTest = subTests.putIfAbsent(name, () => new SubTest());
      subTest.lines[lineIndex] = line;
      int commentIndex = prefix.indexOf('// ');
      if (commentIndex != -1) {
        subTest.expectedError = prefix.substring(commentIndex + 3).trim();
      }
      commonLines.add('');
    } else {
      commonLines.add(line);
    }
    lineIndex++;
  }

  String path = '${location}main.dart';
  Uri entryPoint = Uri.parse('memory:$path');
  await runPositiveTest(
      entryPoint, {path: commonLines.join('\n')}, expectations);
  for (String name in subTests.keys) {
    if (!skipList.contains(name)) {
      SubTest subTest = subTests[name];
      await runNegativeTest(
          subTest, entryPoint, {path: subTest.generateCode(commonLines)});
    }
  }
}

runPositiveTest(Uri entryPoint, Map<String, String> sources,
    Map<String, Kind> expectations) async {
  CompilationResult result =
      await runCompiler(entryPoint: entryPoint, memorySourceFiles: sources);
  Expect.isTrue(result.isSuccess);

  JClosedWorld closedWorld = result.compiler.backendClosedWorldForTesting;
  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;

  void checkClass(ClassEntity cls,
      {bool isNative: false, bool isJsInterop: false}) {
    if (isJsInterop) {
      isNative = true;
    }
    Expect.equals(isJsInterop, closedWorld.nativeData.isJsInteropClass(cls),
        "Unexpected js interop class result for $cls.");
    Expect.equals(isNative, closedWorld.nativeData.isNativeClass(cls),
        "Unexpected native class result for $cls.");
    if (isJsInterop) {
      Expect.isTrue(closedWorld.nativeData.isJsInteropLibrary(cls.library),
          "Unexpected js interop library result for ${cls.library}.");
    }
  }

  void checkMember(MemberEntity member,
      {bool isNative: false, bool isJsInterop: false}) {
    if (isJsInterop) {
      isNative = true;
    }
    Expect.equals(isJsInterop, closedWorld.nativeData.isJsInteropMember(member),
        "Unexpected js interop member result for $member.");
    Expect.equals(isNative, closedWorld.nativeData.isNativeMember(member),
        "Unexpected native member result for $member.");
    if (isJsInterop) {
      Expect.isTrue(closedWorld.nativeData.isJsInteropLibrary(member.library),
          "Unexpected js interop library result for ${member.library}.");
    }
  }

  elementEnvironment.forEachLibraryMember(elementEnvironment.mainLibrary,
      (MemberEntity member) {
    if (member == elementEnvironment.mainFunction) return;

    Kind kind = expectations.remove(member.name);
    Expect.isNotNull(kind, "No expectations for $member");
    checkMember(member,
        isNative: kind == Kind.native, isJsInterop: kind == Kind.jsInterop);
  });

  elementEnvironment.forEachClass(elementEnvironment.mainLibrary,
      (ClassEntity cls) {
    Kind kind = expectations.remove(cls.name);
    Expect.isNotNull(kind, "No expectations for $cls");
    checkClass(cls,
        isNative: kind == Kind.native, isJsInterop: kind == Kind.jsInterop);

    checkClassMember(MemberEntity member) {
      Kind kind = expectations.remove('${cls.name}.${member.name}');
      Expect.isNotNull(kind, "No expectations for $member");
      checkMember(member,
          isNative: kind == Kind.native, isJsInterop: kind == Kind.jsInterop);
    }

    elementEnvironment.forEachConstructor(cls, checkClassMember);
    elementEnvironment.forEachLocalClassMember(cls, checkClassMember);
  });

  Expect.isTrue(expectations.isEmpty, "Untested expectations: $expectations");
}

runNegativeTest(
    SubTest subTest, Uri entryPoint, Map<String, String> sources) async {
  DiagnosticCollector collector = new DiagnosticCollector();
  CompilationResult result = await runCompiler(
      entryPoint: entryPoint,
      memorySourceFiles: sources,
      diagnosticHandler: collector);
  Expect.isFalse(result.isSuccess, "Expected compile time error for\n$subTest");
  Expect.equals(
      1, collector.errors.length, "Expected compile time error for\n$subTest");
  Expect.equals(
      'MessageKind.${subTest.expectedError}',
      collector.errors.first.messageKind.toString(),
      "Unexpected compile time error for\n$subTest");
}

class SubTest {
  String expectedError;
  final Map<int, String> lines = <int, String>{};

  String generateCode(List<String> commonLines) {
    StringBuffer sb = new StringBuffer();
    int i = 0;
    while (i < commonLines.length) {
      if (lines.containsKey(i)) {
        sb.writeln(lines[i]);
      } else {
        sb.writeln(commonLines[i]);
      }
      i++;
    }
    return sb.toString();
  }

  String toString() {
    return lines.values.join('\n');
  }
}
