// Copyright 2019 The Chromium Authors. 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:convert';
import 'dart:io';

import 'package:frontend_server/src/javascript_bundle.dart';
import 'package:frontend_server/src/strong_components.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
import 'package:package_config/package_config.dart';
import 'package:test/test.dart';

/// Additional indexed types required by the dev_compiler's NativeTypeSet.
final Map<String, List<String>> additionalRequiredClasses = {
  'dart:core': ['Comparable'],
  'dart:async': [
    'StreamIterator',
    '_AsyncStarImpl',
  ],
  'dart:_interceptors': [
    'JSBool',
    'JSNumber',
    'JSArray',
    'JSString',
  ],
  'dart:_native_typed_data': [],
  'dart:collection': [
    'ListMixin',
    'MapMixin',
    'LinkedHashSet',
    '_HashSet',
    '_IdentityHashSet',
  ],
  'dart:math': ['Rectangle'],
  'dart:html': [],
  'dart:indexed_db': [],
  'dart:svg': [],
  'dart:web_audio': [],
  'dart:web_gl': [],
  'dart:_js_helper': [
    'PrivateSymbol',
    'LinkedMap',
    'IdentityMap',
    'SyncIterable',
  ],
};

/// Additional indexed top level methods required by the dev_compiler.
final Map<String, List<String>> requiredMethods = {
  'dart:_runtime': ['assertInterop'],
};

void main() {
  final allRequiredTypes =
      _combineMaps(CoreTypes.requiredClasses, additionalRequiredClasses);
  final allRequiredLibraries = {
    ...allRequiredTypes.keys,
    ...requiredMethods.keys
  };
  final testCoreLibraries = [
    for (String requiredLibrary in allRequiredLibraries)
      Library(Uri.parse(requiredLibrary),
          fileUri: Uri.parse(requiredLibrary),
          classes: [
            for (String requiredClass
                in allRequiredTypes[requiredLibrary] ?? [])
              Class(name: requiredClass, fileUri: Uri.parse(requiredLibrary)),
          ],
          procedures: [
            for (var requiredMethod in requiredMethods[requiredLibrary] ?? [])
              Procedure(Name(requiredMethod), ProcedureKind.Method,
                  FunctionNode(EmptyStatement()),
                  fileUri: Uri.parse(requiredLibrary)),
          ]),
  ];

  final packageConfig = PackageConfig.parseJson({
    'configVersion': 2,
    'packages': [
      {
        'name': 'a',
        'rootUri': 'file:///pkg/a',
        'packagesUri': '',
      }
    ],
  }, Uri.base);
  final multiRootScheme = 'org-dartlang-app';

  test('compiles JavaScript code', () async {
    final uri = Uri.file('/c.dart');
    final library = Library(
      uri,
      fileUri: uri,
      procedures: [
        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
            FunctionNode(Block([])),
            fileUri: uri)
      ],
    );
    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
    final strongComponents =
        StrongComponents(testComponent, {}, Uri.file('/c.dart'));
    strongComponents.computeModules();
    final javaScriptBundler = JavaScriptBundler(
        testComponent, strongComponents, multiRootScheme, packageConfig);
    final manifestSink = _MemorySink();
    final codeSink = _MemorySink();
    final sourcemapSink = _MemorySink();
    final metadataSink = _MemorySink();
    final symbolsSink = _MemorySink();
    final coreTypes = CoreTypes(testComponent);

    final compilers = await javaScriptBundler.compile(
      ClassHierarchy(testComponent, coreTypes),
      coreTypes,
      {},
      codeSink,
      manifestSink,
      sourcemapSink,
      metadataSink,
      symbolsSink,
    );

    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
    final String code = utf8.decode(codeSink.buffer);

    expect(manifest, {
      '/c.dart.lib.js': {
        'code': [0, codeSink.buffer.length],
        'sourcemap': [0, sourcemapSink.buffer.length],
      },
    });
    expect(code, contains('ArbitrarilyChosen'));

    // verify source map url is correct.
    expect(code, contains('sourceMappingURL=c.dart.lib.js.map'));

    // verify program compilers are created.
    expect(compilers.keys, equals([urlForComponentUri(library.importUri)]));
  });

  test('converts package: uris into /packages/ uris', () async {
    var importUri = Uri.parse('package:a/a.dart');
    var fileUri = await packageConfig.resolve(importUri);
    final library = Library(
      importUri,
      fileUri: fileUri,
      procedures: [
        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
            FunctionNode(Block([])),
            fileUri: fileUri)
      ],
    );

    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
    final strongComponents = StrongComponents(testComponent, {}, fileUri);
    strongComponents.computeModules();
    final javaScriptBundler = JavaScriptBundler(
        testComponent, strongComponents, multiRootScheme, packageConfig);
    final manifestSink = _MemorySink();
    final codeSink = _MemorySink();
    final sourcemapSink = _MemorySink();
    final metadataSink = _MemorySink();
    final symbolsSink = _MemorySink();
    final coreTypes = CoreTypes(testComponent);

    await javaScriptBundler.compile(
      ClassHierarchy(testComponent, coreTypes),
      coreTypes,
      {},
      codeSink,
      manifestSink,
      sourcemapSink,
      metadataSink,
      symbolsSink,
    );

    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
    final String code = utf8.decode(codeSink.buffer);

    expect(manifest, {
      '/packages/a/a.dart.lib.js': {
        'code': [0, codeSink.buffer.length],
        'sourcemap': [0, sourcemapSink.buffer.length],
      },
    });
    expect(code, contains('ArbitrarilyChosen'));

    // verify source map url is correct.
    expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));
  });

  test('multi-root uris create modules relative to the root', () async {
    var importUri = Uri.parse('$multiRootScheme:/web/main.dart');
    var fileUri = importUri;
    final library = Library(
      importUri,
      fileUri: fileUri,
      procedures: [
        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
            FunctionNode(Block([])),
            fileUri: fileUri)
      ],
    );

    final testComponent = Component(libraries: [library, ...testCoreLibraries]);
    final strongComponents = StrongComponents(testComponent, {}, fileUri);
    strongComponents.computeModules();
    final javaScriptBundler = JavaScriptBundler(
        testComponent, strongComponents, multiRootScheme, packageConfig);
    final manifestSink = _MemorySink();
    final codeSink = _MemorySink();
    final sourcemapSink = _MemorySink();
    final metadataSink = _MemorySink();
    final symbolsSink = _MemorySink();
    final coreTypes = CoreTypes(testComponent);

    await javaScriptBundler.compile(
      ClassHierarchy(testComponent, coreTypes),
      coreTypes,
      {},
      codeSink,
      manifestSink,
      sourcemapSink,
      metadataSink,
      symbolsSink,
    );

    final Map manifest = json.decode(utf8.decode(manifestSink.buffer));
    final String code = utf8.decode(codeSink.buffer);

    expect(manifest, {
      '${importUri.path}.lib.js': {
        'code': [0, codeSink.buffer.length],
        'sourcemap': [0, sourcemapSink.buffer.length],
      },
    });
    expect(code, contains('ArbitrarilyChosen'));

    // verify source map url is correct.
    expect(code, contains('sourceMappingURL=main.dart.lib.js.map'));
  });

  test('can combine strongly connected components', () {
    // Create three libraries A, B, C where A is the entrypoint and B & C
    // circularly import each other.
    final libraryC = Library(Uri.file('/c.dart'), fileUri: Uri.file('/c.dart'));
    final libraryB = Library(Uri.file('/b.dart'), fileUri: Uri.file('/b.dart'));
    libraryC.dependencies.add(LibraryDependency.import(libraryB));
    libraryB.dependencies.add(LibraryDependency.import(libraryC));
    final uriA = Uri.file('/a.dart');
    final libraryA = Library(
      uriA,
      fileUri: uriA,
      dependencies: [
        LibraryDependency.import(libraryB),
      ],
      procedures: [
        Procedure(Name('ArbitrarilyChosen'), ProcedureKind.Method,
            FunctionNode(Block([])),
            fileUri: uriA)
      ],
    );
    final testComponent = Component(
        libraries: [libraryA, libraryB, libraryC, ...testCoreLibraries]);

    final strongComponents =
        StrongComponents(testComponent, {}, Uri.file('/a.dart'));
    strongComponents.computeModules();
    final javaScriptBundler = JavaScriptBundler(
        testComponent, strongComponents, multiRootScheme, packageConfig);
    final manifestSink = _MemorySink();
    final codeSink = _MemorySink();
    final sourcemapSink = _MemorySink();
    final metadataSink = _MemorySink();
    final symbolsSink = _MemorySink();
    final coreTypes = CoreTypes(testComponent);

    javaScriptBundler.compile(
      ClassHierarchy(testComponent, coreTypes),
      coreTypes,
      {},
      codeSink,
      manifestSink,
      sourcemapSink,
      metadataSink,
      symbolsSink,
    );

    final code = utf8.decode(codeSink.buffer);
    final manifest = json.decode(utf8.decode(manifestSink.buffer));

    // There should only be two modules since C and B should be combined.
    final moduleHeader = r"define(['dart_sdk'], (function load__";
    expect(moduleHeader.allMatches(code), hasLength(2));

    // Expected module headers.
    final aModuleHeader =
        r"define(['dart_sdk'], (function load__a_dart(dart_sdk) {";
    expect(code, contains(aModuleHeader));
    final cModuleHeader =
        r"define(['dart_sdk'], (function load__c_dart(dart_sdk) {";
    expect(code, contains(cModuleHeader));

    // verify source map url is correct.
    expect(code, contains('sourceMappingURL=a.dart.lib.js.map'));

    final offsets = manifest['/a.dart.lib.js']['sourcemap'];
    final sourcemapModuleA = json.decode(
        utf8.decode(sourcemapSink.buffer.sublist(offsets.first, offsets.last)));

    // verify source maps are pointing at correct source files.
    expect(sourcemapModuleA['file'], 'a.dart.lib.js');
  });
}

class _MemorySink implements IOSink {
  final List<int> buffer = <int>[];

  @override
  void add(List<int> data) {
    buffer.addAll(data);
  }

  @override
  Future<void> close() => Future.value();

  @override
  void noSuchMethod(Invocation invocation) {
    throw UnsupportedError(invocation.memberName.toString());
  }
}

Map<String, List<String>> _combineMaps(
  Map<String, List<String>> left,
  Map<String, List<String>> right,
) {
  final result = Map<String, List<String>>.from(left);
  for (String key in right.keys) {
    result[key] ??= [];
    result[key].addAll(right[key]);
  }
  return result;
}
