// 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:convert';
import 'dart:io';

import 'package:dev_compiler/src/kernel/module_metadata.dart';
import 'package:test/test.dart';

/// Test creating, reading and writing debugger metadata.
void main() {
  group('Module metadata', () {
    late Directory tempDir;
    late File file;

    setUpAll(() {
      var systemTempDir = Directory.systemTemp;
      tempDir = systemTempDir.createTempSync('foo bar');
      var input = tempDir.uri.resolve('module.metadata');
      file = File.fromUri(input)..createSync();
    });

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

    test('create, write, and read', () async {
      // Create metadata.
      var version = ModuleMetadataVersion.current.version;
      var module = createMetadata(version);
      testMetadataFields(module, version);

      // Write metadata.
      file.writeAsBytesSync(utf8.encode(json.encode(module)));
      expect(file.existsSync(), true);

      // Read metadata.
      var moduleJson = json.decode(utf8.decode(file.readAsBytesSync()));
      var newModule = ModuleMetadata.fromJson(
        moduleJson as Map<String, dynamic>,
      );
      testMetadataFields(newModule, version);
    });

    test('read later backward-compatible patch version', () async {
      // Create metadata with next patch version.
      var version = ModuleMetadataVersion(
        ModuleMetadataVersion.current.majorVersion,
        ModuleMetadataVersion.current.minorVersion,
        ModuleMetadataVersion.current.patchVersion + 1,
      ).version;

      var module = createMetadata(version);

      // Write metadata.
      file.writeAsBytesSync(utf8.encode(json.encode(module)));
      expect(file.existsSync(), true);

      // Read metadata.
      var moduleJson = json.decode(utf8.decode(file.readAsBytesSync()));
      var newModule = ModuleMetadata.fromJson(
        moduleJson as Map<String, dynamic>,
      );
      testMetadataFields(newModule, version);
    });

    test('read later backward-compatible minor version', () async {
      // Create metadata with next minor version.
      var version = ModuleMetadataVersion(
        ModuleMetadataVersion.current.majorVersion,
        ModuleMetadataVersion.current.minorVersion + 1,
        ModuleMetadataVersion.current.patchVersion + 1,
      ).version;
      var module = createMetadata(version);

      // Write metadata.
      file.writeAsBytesSync(utf8.encode(json.encode(module)));
      expect(file.existsSync(), true);

      // Read metadata.
      var moduleJson = json.decode(utf8.decode(file.readAsBytesSync()));
      var newModule = ModuleMetadata.fromJson(
        moduleJson as Map<String, dynamic>,
      );
      testMetadataFields(newModule, version);
    });

    test('fail to read later non-backward-compatible major version', () async {
      // Create metadata with next minor version.
      var version = ModuleMetadataVersion(
        ModuleMetadataVersion.current.majorVersion + 1,
        ModuleMetadataVersion.current.minorVersion + 1,
        ModuleMetadataVersion.current.patchVersion + 1,
      ).version;
      var module = createMetadata(version);

      // Write metadata.
      file.writeAsBytesSync(utf8.encode(json.encode(module)));
      expect(file.existsSync(), true);

      // Try read metadata, expect to fail.
      var moduleJson = json.decode(utf8.decode(file.readAsBytesSync()));
      ModuleMetadata? newModule;
      try {
        newModule = ModuleMetadata.fromJson(moduleJson as Map<String, dynamic>);
      } catch (e) {
        expect(
          e.toString(),
          'Exception: Unsupported metadata version $version',
        );
      }

      expect(newModule, null);
    });
  });
}

ModuleMetadata createMetadata(String version) =>
    ModuleMetadata(
      'module',
      'closure',
      'module.map',
      'module.js',
      'module.full.dill',
      version: version,
    )..addLibrary(
      LibraryMetadata(
        'library',
        'package:library/test.dart',
        'file:///source/library/lib/test.dart',
        ['src/test2.dart'],
      ),
    );

void testMetadataFields(ModuleMetadata module, String version) {
  // Reader always creates current metadata version.
  expect(module.version, version);
  expect(module.name, 'module');
  expect(module.closureName, 'closure');
  expect(module.sourceMapUri, 'module.map');
  expect(module.moduleUri, 'module.js');
  expect(module.fullDillUri, 'module.full.dill');

  var libUri = module.libraries.keys.first;
  var lib = module.libraries[libUri]!;
  expect(libUri, 'package:library/test.dart');
  expect(lib.name, 'library');
  expect(lib.importUri, 'package:library/test.dart');
  expect(lib.fileUri, 'file:///source/library/lib/test.dart');
  expect(lib.partUris[0], 'src/test2.dart');
}
