// Copyright (c) 2020, 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' show Directory, File;

import 'package:dev_compiler/src/compiler/js_names.dart';
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:dev_compiler/src/compiler/shared_command.dart'
    show SharedCompilerOptions;
import 'package:dev_compiler/src/js_ast/js_ast.dart';
import 'package:dev_compiler/src/kernel/compiler.dart' show ProgramCompiler;
import 'package:dev_compiler/src/kernel/expression_compiler.dart'
    show ExpressionCompiler;
import 'package:kernel/ast.dart' show Component, Library;
import 'package:test/test.dart';
import 'package:vm/transformations/type_flow/utils.dart';

import '../shared_test_options.dart';

// TODO(annagrin): Replace javascript matching in tests below with evaluating
// the javascript and checking the result.
// See https://github.com/dart-lang/sdk/issues/41959

/// Convenience class describing JavaScript module
/// to ensure we have normalized module names
class Module {
  /// variable name used in JavaScript output to load the module
  /// example: file
  final String name;

  /// JavaScript module name used in trackLibraries
  /// example: packages/package/file.dart
  final String path;

  /// URI where the contents of the library that produces this module
  /// can be found
  /// example: /Users/../package/file.dart
  final Uri fileUri;

  /// Import URI for the library that generates this module.
  /// example: packages:package/file.dart
  final Uri importUri;

  Module(this.importUri, this.fileUri)
      : name = libraryUriToJsIdentifier(importUri),
        path = importUri.isScheme('package')
            ? 'packages/${importUri.path}'
            : importUri.path;

  String get package => importUri.toString();
  String get file => fileUri.path;

  @override
  String toString() =>
      'Name: \$name, File: \$file, Package: \$package, path: \$path';
}

class TestCompilationResult {
  final String result;
  final bool isSuccess;

  TestCompilationResult(this.result, this.isSuccess);
}

class TestCompiler {
  final SetupCompilerOptions setup;

  TestCompiler(this.setup);

  Future<TestCompilationResult> compile(
      {required Uri input,
      required Uri packages,
      required int line,
      required int column,
      required Map<String, String> scope,
      required String expression}) async {
    // initialize incremental compiler and create component
    setup.options.packagesFileUri = packages;
    var compiler = DevelopmentIncrementalCompiler(setup.options, input);
    var compilerResult = await compiler.computeDelta();
    var component = compilerResult.component;
    component.computeCanonicalNames();

    // initialize ddc
    var moduleName = 'foo.dart';
    var classHierarchy = compilerResult.classHierarchy;
    var compilerOptions = SharedCompilerOptions(
        replCompile: true,
        moduleName: moduleName,
        soundNullSafety: setup.soundNullSafety,
        moduleFormats: [setup.moduleFormat]);
    var coreTypes = compilerResult.coreTypes;

    final importToSummary = Map<Library, Component>.identity();
    final summaryToModule = Map<Component, String>.identity();
    for (var lib in component.libraries) {
      importToSummary[lib] = component;
    }
    summaryToModule[component] = moduleName;

    var kernel2jsCompiler = ProgramCompiler(component, classHierarchy!,
        compilerOptions, importToSummary, summaryToModule,
        coreTypes: coreTypes);
    var moduleTree = kernel2jsCompiler.emitModule(component);

    {
      var opts = JavaScriptPrintingOptions(
          allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
      var printer = SimpleJavaScriptPrintingContext();

      var tree = transformModuleFormat(setup.moduleFormat, moduleTree);
      tree.accept(Printer(opts, printer, localNamer: TemporaryNamer(tree)));
      var printed = printer.getText();
      debugPrint(printed);
    }

    // create expression compiler
    var evaluator = ExpressionCompiler(
      setup.options,
      setup.moduleFormat,
      setup.errors,
      compiler,
      kernel2jsCompiler,
      component,
    );

    // collect all module names and paths
    var moduleInfo = _collectModules(component);
    var module = moduleInfo[input]!;

    setup.errors.clear();

    // compile
    var jsExpression = await evaluator.compileExpressionToJs(
        module.package, line, column, scope, expression);

    if (setup.errors.isNotEmpty) {
      jsExpression = setup.errors.toString().replaceAll(
          RegExp(
              r'org-dartlang-debug:synthetic_debug_expression:[0-9]*:[0-9]*:'),
          '');

      return TestCompilationResult(jsExpression, false);
    }

    return TestCompilationResult(jsExpression!, true);
  }

  Map<Uri, Module> _collectModules(Component component) {
    var modules = <Uri, Module>{};
    for (var library in component.libraries) {
      modules[library.fileUri] = Module(library.importUri, library.fileUri);
    }

    return modules;
  }
}

class TestDriver {
  final SetupCompilerOptions options;
  late Directory tempDir;
  final String source;
  late Uri input;
  late Uri packages;
  late File file;
  int line;

  TestDriver(this.options, this.source) : line = _getEvaluationLine(source) {
    var systemTempDir = Directory.systemTemp;
    tempDir = systemTempDir.createTempSync('foo bar');

    input = tempDir.uri.resolve('foo.dart');
    file = File.fromUri(input)..createSync();
    file.writeAsStringSync(source);

    packages = tempDir.uri.resolve('package_config.json');
    file = File.fromUri(packages)..createSync();
    file.writeAsStringSync('''
      {
        "configVersion": 2,
        "packages": [
          {
            "name": "foo",
            "rootUri": "./",
            "packageUri": "./"
          }
        ]
      }
      ''');
  }

  void delete() {
    tempDir.delete(recursive: true);
  }

  Future<void> check(
      {required Map<String, String> scope,
      required String expression,
      String? expectedError,
      String? expectedResult}) async {
    var result = await TestCompiler(options).compile(
        input: input,
        packages: packages,
        line: line,
        column: 1,
        scope: scope,
        expression: expression);

    var success = expectedError == null;
    var message = success ? expectedResult! : expectedError;

    expect(
        result,
        const TypeMatcher<TestCompilationResult>()
            .having((r) => _normalize(r.result), 'result', _matches(message))
            .having((r) => r.isSuccess, 'isSuccess', success));
  }

  String _normalize(String text) {
    return text
        .replaceAll(RegExp('\'.*foo.dart\''), '\'foo.dart\'')
        .replaceAll(RegExp('".*foo.dart"'), '\'foo.dart\'');
  }

  Matcher _matches(String text) {
    var unindented = RegExp.escape(text).replaceAll(RegExp('[ ]+'), '[ ]*');
    return matches(RegExp(unindented, multiLine: true));
  }

  static int _getEvaluationLine(String source) {
    var placeholderRegExp = RegExp(r'/\* evaluation placeholder \*/');

    var lines = source.split('\n');
    for (var line = 0; line < lines.length; line++) {
      var content = lines[line];
      if (placeholderRegExp.firstMatch(content) != null) {
        return line + 1;
      }
    }
    return -1;
  }
}

void main() {
  for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
    group('Module format: $moduleFormat', () {
      group('Unsound null safety:', () {
        var options = SetupCompilerOptions(
            soundNullSafety: false, moduleFormat: moduleFormat);

        group('Expression compiler import tests', () {
          var source = '''
          ${options.dartLangComment}
          import 'dart:io' show Directory;
          import 'dart:io' as p;
          import 'dart:convert' as p;
          
          main() {
            print(Directory.systemTemp);
            print(p.Directory.systemTemp);
            print(p.utf.decoder);
          }

          void foo() {
            /* evaluation placeholder */
          }
          ''';

          late TestDriver driver;

          setUp(() {
            driver = TestDriver(options, source);
          });

          tearDown(() {
            driver.delete();
          });

          test('expression referencing unnamed import', () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'Directory.systemTemp',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const io = dart_sdk.io;
              return io.Directory.systemTemp;
            }(
              
            ))
            ''');
          });

          test('expression referencing named import', () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'p.Directory.systemTemp',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const io = dart_sdk.io;
              return io.Directory.systemTemp;
            }(
              
            ))
            ''');
          });

          test(
              'expression referencing another library with the same named import',
              () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'p.utf8.decoder',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const convert = dart_sdk.convert;
              return convert.utf8.decoder;
            }(
              
            ))
            ''');
          });
        });

        group(
            'Expression compiler tests for interactions with module containers:',
            () {
          var source = '''
          ${options.dartLangComment}
          class A {
            const A();
          }
          class B {
            const B();
          }
          void foo() {
            const a = A();
            var check = a is int;
            /* evaluation placeholder */
            return;
          }

          void main() => foo();
          ''';

          late TestDriver driver;
          setUp(() {
            driver = TestDriver(options, source);
          });

          tearDown(() {
            driver.delete();
          });

          test(
              'evaluation that non-destructively appends to the type container',
              () async {
            await driver.check(
                scope: <String, String>{'a': 'null', 'check': 'null'},
                expression: 'a is String',
                expectedResult: '''
            (function(a, check) {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const core = dart_sdk.core;
              const dart = dart_sdk.dart;
              var T = {
                StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))()
              };
              return T.StringL().is(a);
            }(
              null,
              null
            ))
            ''');
          });

          test('evaluation that reuses the type container', () async {
            await driver.check(
                scope: <String, String>{'a': 'null', 'check': 'null'},
                expression: 'a is int',
                expectedResult: '''
            (function(a, check) {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const core = dart_sdk.core;
              const dart = dart_sdk.dart;
              var T = {
                intL: () => (T.intL = dart.constFn(dart.legacy(core.int)))()
              };
              return T.intL().is(a);
            }(
              null,
              null
            ))
            ''');
          });

          test(
              'evaluation that non-destructively appends to the constant container',
              () async {
            await driver.check(
                scope: <String, String>{'a': 'null', 'check': 'null'},
                expression: 'const B()',
                expectedResult: '''
            (function(a, check) {
             const dart_sdk = ${options.loadModule}('dart_sdk');
              const dart = dart_sdk.dart;
              const foo\$46dart = ${options.loadModule}('foo.dart');
              const foo = foo\$46dart.foo;
              const CT = Object.create(null);
              dart.defineLazy(CT, {
                get C0() {
                  return C[0] = dart.const({
                    __proto__: foo.B.prototype
                  });
                }
              }, false);
              var C = [void 0];
              return C[0] || CT.C0;
            }(
              null,
              null
            ))
            ''');
          });

          test(
              'evaluation that reuses the constant container and canonicalizes properly',
              () async {
            await driver.check(
                scope: <String, String>{'a': 'null', 'check': 'null'},
                expression: 'a == const A()',
                expectedResult: '''
            (function(a, check) {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const dart = dart_sdk.dart;
              const foo\$46dart = ${options.loadModule}('foo.dart');
              const foo = foo\$46dart.foo;
              const CT = Object.create(null);
              dart.defineLazy(CT, {
                get C0() {
                  return C[0] = dart.const({
                    __proto__: foo.A.prototype
                  });
                }
              }, false);
              var C = [void 0];
              return dart.equals(a, C[0] || CT.C0);
            }(
              null,
              null
            ))
            ''');
          });
        });

        group('Expression compiler tests using extension symbols', () {
          var source = '''
          ${options.dartLangComment}
          void bar() {
            /* evaluation placeholder */
          }

          void main() => bar();
          ''';

          late TestDriver driver;
          setUp(() {
            driver = TestDriver(options, source);
          });

          tearDown(() {
            driver.delete();
          });

          test('map access', () async {
            await driver.check(
                scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
                expression:
                    '(Map<String, String> params) { return params["index"]; }({})',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const core = dart_sdk.core;
              const _js_helper = dart_sdk._js_helper;
              const dart = dart_sdk.dart;
              const dartx = dart_sdk.dartx;
              var T = {
                StringL: () => (T.StringL = dart.constFn(dart.legacy(core.String)))(),
                MapOfStringL\$StringL: () => (T.MapOfStringL\$StringL = dart.constFn(core.Map\$(T.StringL(), T.StringL())))(),
                MapLOfStringL\$StringL: () => (T.MapLOfStringL\$StringL = dart.constFn(dart.legacy(T.MapOfStringL\$StringL())))(),
                MapLOfStringL\$StringLToStringL: () => (T.MapLOfStringL\$StringLToStringL = dart.constFn(dart.fnType(T.StringL(), [T.MapLOfStringL\$StringL()])))(),
                IdentityMapOfStringL\$StringL: () => (T.IdentityMapOfStringL\$StringL = dart.constFn(_js_helper.IdentityMap\$(T.StringL(), T.StringL())))()
              };
              var S = {\$_get: dartx._get};
              return dart.fn(params => params[S.\$_get]("index"), T.MapLOfStringL\$StringLToStringL())(new (T.IdentityMapOfStringL\$StringL()).new());
            }(
              
            ))
            ''');
          });
        });
      });
    });
  }

  for (var moduleFormat in [ModuleFormat.amd, ModuleFormat.ddc]) {
    group('Module format: $moduleFormat', () {
      group('Sound null safety:', () {
        var options = SetupCompilerOptions(soundNullSafety: true);

        group('Expression compiler import tests', () {
          var source = '''
          ${options.dartLangComment}
          import 'dart:io' show Directory;
          import 'dart:io' as p;
          import 'dart:convert' as p;
          
          main() {
            print(Directory.systemTemp);
            print(p.Directory.systemTemp);
            print(p.utf.decoder);
          }

          void foo() {
            /* evaluation placeholder */
          }
          ''';

          late TestDriver driver;

          setUp(() {
            driver = TestDriver(options, source);
          });

          tearDown(() {
            driver.delete();
          });

          test('expression referencing unnamed import', () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'Directory.systemTemp',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const io = dart_sdk.io;
              return io.Directory.systemTemp;
            }(
              
            ))
            ''');
          });

          test('expression referencing named import', () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'p.Directory.systemTemp',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const io = dart_sdk.io;
              return io.Directory.systemTemp;
            }(
              
            ))
            ''');
          });

          test(
              'expression referencing another library with the same named import',
              () async {
            await driver.check(
                scope: <String, String>{},
                expression: 'p.utf8.decoder',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const convert = dart_sdk.convert;
              return convert.utf8.decoder;
            }(
              
            ))
            ''');
          });
        });

        group('Expression compiler expressions that import extension symbols',
            () {
          var source = '''
          ${options.dartLangComment}
          void bar() {
            /* evaluation placeholder */ 
          }

          void main() => bar();
          ''';

          late TestDriver driver;
          setUp(() {
            driver = TestDriver(options, source);
          });

          tearDown(() {
            driver.delete();
          });

          test('map access', () async {
            await driver.check(
                scope: <String, String>{'inScope': '1', 'innerInScope': '0'},
                expression:
                    '(Map<String, String> params) { return params["index"]; }({})',
                expectedResult: '''
            (function() {
              const dart_sdk = ${options.loadModule}('dart_sdk');
              const core = dart_sdk.core;
              const _js_helper = dart_sdk._js_helper;
              const dart = dart_sdk.dart;
              const dartx = dart_sdk.dartx;
              var T = {
                StringN: () => (T.StringN = dart.constFn(dart.nullable(core.String)))(),
                MapOfString\$String: () => (T.MapOfString\$String = dart.constFn(core.Map\$(core.String, core.String)))(),
                MapOfString\$StringToStringN: () => (T.MapOfString\$StringToStringN = dart.constFn(dart.fnType(T.StringN(), [T.MapOfString\$String()])))(),
                IdentityMapOfString\$String: () => (T.IdentityMapOfString\$String = dart.constFn(_js_helper.IdentityMap\$(core.String, core.String)))()
              };
              var S = {\$_get: dartx._get};
              return dart.fn(params => params[S.\$_get]("index"), T.MapOfString\$StringToStringN())(new (T.IdentityMapOfString\$String()).new());
            }(
              
            ))
            ''');
          });
        });
      });
    });
  }
}
