// 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:web_sql': [],
  '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 coreTypes = CoreTypes(testComponent);

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

    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 coreTypes = CoreTypes(testComponent);

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

    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 coreTypes = CoreTypes(testComponent);

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

    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 coreTypes = CoreTypes(testComponent);

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

    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;
}
