// 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';

import 'package:path/path.dart' as path;
import 'package:test/test.dart';

import 'package:vm/snapshot/instruction_sizes.dart' as instruction_sizes;

void main() async {
  if (!Platform.executable.contains('dart-sdk')) {
    // If we are not running from the prebuilt SDK then this test does nothing.
    return;
  }

  final sdkBin = path.dirname(Platform.executable);
  final dart2native =
      path.join(sdkBin, Platform.isWindows ? 'dart2native.bat' : 'dart2native');

  if (!File(dart2native).existsSync()) {
    throw 'Failed to locate dart2native in the SDK';
  }

  group('instruction-sizes', () {
    test('basic-parsing', () async {
      await withTempDir('basic-parsing', (dir) async {
        final inputDart = path.join(dir, 'input.dart');
        final outputBinary = path.join(dir, 'output.exe');
        final sizesJson = path.join(dir, 'sizes.json');

        // Create test input.
        await File(inputDart).writeAsString("""
@pragma('vm:never-inline')
dynamic makeSomeClosures() {
  return [
    () => true,
    () => false,
    () => 11,
  ];
}

class A {
  @pragma('vm:never-inline')
  dynamic tornOff() {
    return true;
  }
}

class B {
  @pragma('vm:never-inline')
  dynamic tornOff() {
    return false;
  }
}

@pragma('vm:never-inline')
Function tearOff(dynamic o) {
  return o.tornOff;
}

void main(List<String> args) {
  for (var cl in makeSomeClosures()) {
    print(cl());
  }
  print(tearOff(args.isEmpty ? A() : B()));
}
""");

        // Compile input.dart to native and output instruction sizes.
        final result = await Process.run(dart2native, [
          '-o',
          outputBinary,
          '--extra-gen-snapshot-options=--print_instructions_sizes_to=$sizesJson',
          inputDart,
        ]);

        expect(result.exitCode, equals(0),
            reason: 'Compilation completed successfully');
        expect(File(outputBinary).existsSync(), isTrue,
            reason: 'Output binary exists');
        expect(File(sizesJson).existsSync(), isTrue,
            reason: 'Instruction sizes output exists');

        final symbols = await instruction_sizes.load(File(sizesJson));
        expect(symbols, isNotNull,
            reason: 'Sizes file was successfully parsed');
        expect(symbols.length, greaterThan(0),
            reason: 'Sizes file is non-empty');

        // Check for duplicated symbols (using both raw and scrubbed names).
        final symbolRawNamesByLibrary = Map<String, Set<String>>();
        final symbolScrubbedNamesByLibrary = Map<String, Set<String>>();

        Set<String> getSetOfNames(
            Map<String, Set<String>> map, String libraryUri) {
          // For file uris make sure to canonicalize the path. This prevents
          // issues with mismatching case on Windows which has case insensitive
          // file system.
          if (libraryUri != null) {
            final uri = Uri.parse(libraryUri);
            if (uri.scheme == 'file') {
              libraryUri =
                  Uri.file(path.canonicalize(uri.toFilePath())).toString();
            }
          }
          return map.putIfAbsent(libraryUri ?? '', () => {});
        }

        for (var sym in symbols) {
          expect(
              getSetOfNames(symbolRawNamesByLibrary, sym.libraryUri)
                  .add(sym.name.raw),
              isTrue,
              reason:
                  'All symbols should have unique names (within libraries): ${sym.name.raw}');
          expect(
              getSetOfNames(symbolScrubbedNamesByLibrary, sym.libraryUri)
                  .add(sym.name.scrubbed),
              isTrue,
              reason: 'Scrubbing the name should not make it non-unique');
        }

        // Check for expected names which should appear in the output.
        final inputDartSymbolNames = symbolScrubbedNamesByLibrary[
            Uri.file(path.canonicalize(inputDart)).toString()];
        expect(inputDartSymbolNames, isNotNull,
            reason: 'Symbols from input.dart are included into sizes output');

        expect(inputDartSymbolNames, contains('makeSomeClosures'));
        final closures = inputDartSymbolNames.where(
            (name) => name.startsWith('makeSomeClosures.<anonymous closure'));
        expect(closures.length, 3);
        expect(inputDartSymbolNames, contains('A.tornOff'));
        expect(inputDartSymbolNames, contains('[tear-off] A.tornOff'));
        expect(inputDartSymbolNames,
            contains('[tear-off-extractor] A.get:tornOff'));
        expect(inputDartSymbolNames, contains('B.tornOff'));
        expect(inputDartSymbolNames, contains('[tear-off] B.tornOff'));
        expect(inputDartSymbolNames,
            contains('[tear-off-extractor] B.get:tornOff'));
      });
    });
  });
}

Future withTempDir(String prefix, Future fun(String dir)) async {
  final tempDir =
      Directory.systemTemp.createTempSync('instruction-sizes-test-${prefix}');
  try {
    await fun(tempDir.path);
  } finally {
    tempDir.deleteSync(recursive: true);
  }
}
