// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/deferred_component.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/logger.dart';

import '../../src/common.dart';
import '../../src/context.dart';

void main() {
  group('DeferredComponent basics', () {
    test('constructor sets values', () {
      final DeferredComponent component = DeferredComponent(
        name: 'bestcomponent',
        libraries: <String>['lib1', 'lib2'],
        assets: <Uri>[Uri.file('asset1'), Uri.file('asset2')],
      );
      expect(component.name, 'bestcomponent');
      expect(component.libraries, <String>['lib1', 'lib2']);
      expect(component.assets, <Uri>[Uri.file('asset1'), Uri.file('asset2')]);
    });

    test('assignLoadingUnits selects the needed loading units and sets assigned', () {
      final DeferredComponent component = DeferredComponent(
        name: 'bestcomponent',
        libraries: <String>['lib1', 'lib2'],
        assets: <Uri>[Uri.file('asset1'), Uri.file('asset2')],
      );
      expect(component.libraries, <String>['lib1', 'lib2']);
      expect(component.assigned, false);
      expect(component.loadingUnits, null);

      final List<LoadingUnit> loadingUnits1 = <LoadingUnit>[
        LoadingUnit(
          id: 2,
          path: 'path/to/so.so',
          libraries: <String>['lib1', 'lib4'],
        ),
        LoadingUnit(
          id: 3,
          path: 'path/to/so.so',
          libraries: <String>['lib2', 'lib5'],
        ),
        LoadingUnit(
          id: 4,
          path: 'path/to/so.so',
          libraries: <String>['lib6', 'lib7'],
        ),
      ];

      component.assignLoadingUnits(loadingUnits1);

      expect(component.assigned, true);
      expect(component.loadingUnits.length, 2);
      expect(component.loadingUnits.contains(loadingUnits1[0]), true);
      expect(component.loadingUnits.contains(loadingUnits1[1]), true);
      expect(component.loadingUnits.contains(loadingUnits1[2]), false);

      final List<LoadingUnit> loadingUnits2 = <LoadingUnit>[
        LoadingUnit(
          id: 2,
          path: 'path/to/so.so',
          libraries: <String>['lib1', 'lib2'],
        ),
        LoadingUnit(
          id: 3,
          path: 'path/to/so.so',
          libraries: <String>['lib5', 'lib6'],
        ),
        LoadingUnit(
          id: 4,
          path: 'path/to/so.so',
          libraries: <String>['lib7', 'lib8'],
        ),
      ];
      // Can reassign loading units.
      component.assignLoadingUnits(loadingUnits2);

      expect(component.assigned, true);
      expect(component.loadingUnits.length, 1);
      expect(component.loadingUnits.contains(loadingUnits2[0]), true);
      expect(component.loadingUnits.contains(loadingUnits2[1]), false);
      expect(component.loadingUnits.contains(loadingUnits2[2]), false);

      component.assignLoadingUnits(<LoadingUnit>[]);

      expect(component.assigned, true);
      expect(component.loadingUnits.length, 0);
    });

    test('toString produces correct string for unassigned component', () {
      final DeferredComponent component = DeferredComponent(
        name: 'bestcomponent',
        libraries: <String>['lib1', 'lib2'],
        assets: <Uri>[Uri.file('asset1'), Uri.file('asset2')],
      );
      expect(component.toString(), '\nDeferredComponent: bestcomponent\n  Libraries:\n    - lib1\n    - lib2\n  Assets:\n    - asset1\n    - asset2');
    });

    test('toString produces correct string for assigned component', () {
      final DeferredComponent component = DeferredComponent(
        name: 'bestcomponent',
        libraries: <String>['lib1', 'lib2'],
        assets: <Uri>[Uri.file('asset1'), Uri.file('asset2')],
      );
      component.assignLoadingUnits(<LoadingUnit>[LoadingUnit(id: 2, libraries: <String>['lib1'])]);
      expect(component.toString(), '\nDeferredComponent: bestcomponent\n  Libraries:\n    - lib1\n    - lib2\n  LoadingUnits:\n    - 2\n  Assets:\n    - asset1\n    - asset2');
    });
  });

  group('LoadingUnit basics', () {
    test('constructor sets values', () {
      final LoadingUnit unit = LoadingUnit(
        id: 2,
        path: 'path/to/so.so',
        libraries: <String>['lib1', 'lib4'],
      );
      expect(unit.id, 2);
      expect(unit.path, 'path/to/so.so');
      expect(unit.libraries, <String>['lib1', 'lib4']);
    });

    test('toString produces correct string', () {
      final LoadingUnit unit = LoadingUnit(
        id: 2,
        path: 'path/to/so.so',
        libraries: <String>['lib1', 'lib4'],
      );
      expect(unit.toString(),'\nLoadingUnit 2\n  Libraries:\n  - lib1\n  - lib4');
    });

    test('equalsIgnoringPath works for various input', () {
      final LoadingUnit unit1 = LoadingUnit(
        id: 2,
        path: 'path/to/so.so',
        libraries: <String>['lib1', 'lib4'],
      );
      final LoadingUnit unit2 = LoadingUnit(
        id: 2,
        path: 'path/to/other/so.so',
        libraries: <String>['lib1', 'lib4'],
      );
      final LoadingUnit unit3 = LoadingUnit(
        id: 1,
        path: 'path/to/other/so.so',
        libraries: <String>['lib1', 'lib4'],
      );
      final LoadingUnit unit4 = LoadingUnit(
        id: 1,
        path: 'path/to/other/so.so',
        libraries: <String>['lib1'],
      );
      final LoadingUnit unit5 = LoadingUnit(
        id: 1,
        path: 'path/to/other/so.so',
        libraries: <String>['lib2'],
      );
      final LoadingUnit unit6 = LoadingUnit(
        id: 1,
        path: 'path/to/other/so.so',
        libraries: <String>['lib1', 'lib5'],
      );
      expect(unit1.equalsIgnoringPath(unit2), true);
      expect(unit2.equalsIgnoringPath(unit3), false);
      expect(unit3.equalsIgnoringPath(unit4), false);
      expect(unit4.equalsIgnoringPath(unit5), false);
      expect(unit5.equalsIgnoringPath(unit6), false);
    });

    test('parseLoadingUnitManifest parses single manifest file', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final File manifest = fileSystem.file('/manifest.json');
      manifest.createSync(recursive: true);
      manifest.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/arm64-v8a\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/arm64-v8a\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/arm64-v8a\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
] }

''', flush: true);
      final List<LoadingUnit> loadingUnits = LoadingUnit.parseLoadingUnitManifest(manifest, BufferLogger.test());
      expect(loadingUnits.length, 2); // base module (id 1) is not parsed.
      expect(loadingUnits[0].id, 2);
      expect(loadingUnits[0].path, '/arm64-v8a/app.so-2.part.so');
      expect(loadingUnits[0].libraries.length, 1);
      expect(loadingUnits[0].libraries[0], 'lib2');
      expect(loadingUnits[1].id, 3);
      expect(loadingUnits[1].path, '/arm64-v8a/app.so-3.part.so');
      expect(loadingUnits[1].libraries.length, 2);
      expect(loadingUnits[1].libraries[0], 'lib3');
      expect(loadingUnits[1].libraries[1], 'lib4');
    });

    testUsingContext('parseLoadingUnitManifest returns empty when manifest is invalid JSON', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final File manifest = fileSystem.file('/manifest.json');
      manifest.createSync(recursive: true);
      // invalid due to missing closing brace `}`
      manifest.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/arm64-v8a\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/arm64-v8a\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/arm64-v8a\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
]

''', flush: true);
      final List<LoadingUnit> loadingUnits = LoadingUnit.parseLoadingUnitManifest(manifest, BufferLogger.test());
      expect(loadingUnits.length, 0);
      expect(loadingUnits.isEmpty, true);
    });

    testUsingContext('parseLoadingUnitManifest does not exist', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final File manifest = fileSystem.file('/manifest.json');
      if (manifest.existsSync()) {
        manifest.deleteSync(recursive: true);
      }
      final List<LoadingUnit> loadingUnits = LoadingUnit.parseLoadingUnitManifest(manifest, BufferLogger.test());
      expect(loadingUnits.length, 0);
      expect(loadingUnits.isEmpty, true);
    });

    test('parseGeneratedLoadingUnits parses all abis if no abis provided', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final File manifest1 = fileSystem.file('/test-abi1/manifest.json');
      manifest1.createSync(recursive: true);
      manifest1.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/test-abi1\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/test-abi1\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/test-abi1\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
] }

''', flush: true);
      final File manifest2 = fileSystem.file('/test-abi2/manifest.json');
      manifest2.createSync(recursive: true);
      manifest2.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/test-abi2\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/test-abi2\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/test-abi2\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
] }

''', flush: true);
      final List<LoadingUnit> loadingUnits =
          LoadingUnit.parseGeneratedLoadingUnits(fileSystem.directory('/'), BufferLogger.test());
      expect(loadingUnits.length, 4); // base module (id 1) is not parsed.

      expect(loadingUnits[0].id, 2);
      expect(loadingUnits[0].path, '/test-abi2/app.so-2.part.so');
      expect(loadingUnits[0].libraries.length, 1);
      expect(loadingUnits[0].libraries[0], 'lib2');
      expect(loadingUnits[1].id, 3);
      expect(loadingUnits[1].path, '/test-abi2/app.so-3.part.so');
      expect(loadingUnits[1].libraries.length, 2);
      expect(loadingUnits[1].libraries[0], 'lib3');
      expect(loadingUnits[1].libraries[1], 'lib4');

      expect(loadingUnits[2].id, 2);
      expect(loadingUnits[2].path, '/test-abi1/app.so-2.part.so');
      expect(loadingUnits[2].libraries.length, 1);
      expect(loadingUnits[2].libraries[0], 'lib2');
      expect(loadingUnits[3].id, 3);
      expect(loadingUnits[3].path, '/test-abi1/app.so-3.part.so');
      expect(loadingUnits[3].libraries.length, 2);
      expect(loadingUnits[3].libraries[0], 'lib3');
      expect(loadingUnits[3].libraries[1], 'lib4');
    });

    test('parseGeneratedLoadingUnits only parses provided abis', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final File manifest1 = fileSystem.file('/test-abi1/manifest.json');
      manifest1.createSync(recursive: true);
      manifest1.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/test-abi1\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/test-abi1\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/test-abi1\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
] }

''', flush: true);
      final File manifest2 = fileSystem.file('/test-abi2/manifest.json');
      manifest2.createSync(recursive: true);
      manifest2.writeAsStringSync(r'''
{ "loadingUnits": [
{ "id": 1, "path": "\/test-abi2\/app.so", "libraries": [
"dart:core"]}
,
{ "id": 2, "path": "\/test-abi2\/app.so-2.part.so", "libraries": [
"lib2"]}
,
{ "id": 3, "path": "\/test-abi2\/app.so-3.part.so", "libraries": [
"lib3", "lib4"]}
] }

''', flush: true);
      final List<LoadingUnit> loadingUnits =
          LoadingUnit.parseGeneratedLoadingUnits(fileSystem.directory('/'), BufferLogger.test(), abis: <String>['test-abi2']);
      expect(loadingUnits.length, 2); // base module (id 1) is not parsed.

      expect(loadingUnits[0].id, 2);
      expect(loadingUnits[0].path, '/test-abi2/app.so-2.part.so');
      expect(loadingUnits[0].libraries.length, 1);
      expect(loadingUnits[0].libraries[0], 'lib2');
      expect(loadingUnits[1].id, 3);
      expect(loadingUnits[1].path, '/test-abi2/app.so-3.part.so');
      expect(loadingUnits[1].libraries.length, 2);
      expect(loadingUnits[1].libraries[0], 'lib3');
      expect(loadingUnits[1].libraries[1], 'lib4');
    });

    test('parseGeneratedLoadingUnits returns empty when no manifest files exist', () {
      final FileSystem fileSystem = MemoryFileSystem.test();
      final List<LoadingUnit> loadingUnits =
          LoadingUnit.parseGeneratedLoadingUnits(fileSystem.directory('/'), BufferLogger.test());
      expect(loadingUnits.isEmpty, true);
      expect(loadingUnits.length, 0);
    });
  });
}
