// Copyright (c) 2025, 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 'dart:io' as io;
import 'dart:typed_data';

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

import 'package:wasm_builder/src/ir/ir.dart';
import 'package:wasm_builder/src/serialize/deserializer.dart';
import 'package:wasm_builder/src/serialize/printer.dart';

import 'util.dart';

void main(List<String> args) async {
  final result = argParser.parse(args);
  final help = result.flag('help');
  final write = result.flag('write');
  final runFromSource = result.flag('src');
  final filter = result.option('filter');

  if (help) {
    print('Usage:\n${argParser.usage}');
    io.exit(0);
  }
  if (result.rest.isNotEmpty) {
    print('Unknown arguments: ${result.rest.join(' ')}');
    print('Usage:\n${argParser.usage}');
    io.exit(1);
  }

  final filterRegExp = filter != null ? RegExp(filter) : null;

  await withTempDir((String tempDir) async {
    for (final dartFilename in listIrTests()) {
      // Ignore helper files (e.g. tests may use deferred modules which requires
      // multiple dart files to test).
      if (dartFilename.contains('.h.')) {
        continue;
      }

      if (filterRegExp != null && !filterRegExp.hasMatch(dartFilename)) {
        continue;
      }

      void failTest() {
        print('-> test "$dartFilename" failed\n');
        io.exitCode = 254;
      }

      final dartCode = File(dartFilename).readAsStringSync();
      final wasmFile = File(path.join(
          tempDir, path.setExtension(path.basename(dartFilename), '.wasm')));

      final (settings, compilerOptions) = parseSettings(dartCode);

      print('\nTesting $dartFilename');

      final result = await Process.run('/usr/bin/env', [
        'bash',
        'pkg/dart2wasm/tool/compile_benchmark',
        for (final option in compilerOptions) '--extra-compiler-option=$option',
        if (runFromSource) '--src',
        '--no-strip-wasm',
        '-o',
        wasmFile.path,
        dartFilename
      ]);
      if (result.exitCode != 0) {
        print('Compilation failed:');
        print('stdout:\n${result.stdout}');
        print('stderr:\n${result.stderr}\n');
        failTest();
        continue;
      }

      final deferredModulePrefix =
          '${path.withoutExtension(wasmFile.path)}_mod';
      final deferredModuleWasmFiles = wasmFile.parent
          .listSync()
          .whereType<File>()
          .where((fse) =>
              fse.path.endsWith('.wasm') &&
              fse.path.startsWith(deferredModulePrefix))
          .toList();

      for (final file in [wasmFile, ...deferredModuleWasmFiles]) {
        final module = parseModule(file.readAsBytesSync());
        final wat = module.printAsWat(settings: settings);
        final watFile = File(path.join(path.dirname(dartFilename),
            path.setExtension(path.basename(file.path), '.wat')));

        if (write) {
          print('-> Updated expectation file: ${watFile.path}');
          watFile.writeAsStringSync(wat);
          continue;
        }
        if (!watFile.existsSync()) {
          print('Expected "${watFile.path}" to exist.');
          failTest();
          continue;
        }

        final oldWat = watFile.readAsStringSync();
        if (oldWat != wat) {
          print('-> Expectation of ${path.basename(watFile.path)} mismatch: ');
          print('Expected:\n  ${oldWat.split('\n').join('\n  ')}');
          print('Actual:\n  ${wat.split('\n').join('\n  ')}');
          print('-> Run with `-w` to update expectation file.');
          failTest();
          continue;
        }
      }
    }
  });
}

final argParser = ArgParser()
  ..addFlag('help',
      abbr: 'h', defaultsTo: false, help: 'Prints available options.')
  ..addFlag('src', defaultsTo: false, help: 'Runs the compiler from source.')
  ..addOption('filter',
      abbr: 'f', help: 'Runs only tests that match the filter.')
  ..addFlag('write',
      abbr: 'w', defaultsTo: false, help: 'Writes new expectation files.');

Iterable<String> listIrTests() {
  return Directory('pkg/dart2wasm/test/ir_tests')
      .listSync(recursive: true)
      .whereType<File>()
      .map((file) => file.path)
      .where((path) => path.endsWith('.dart'));
}

Module parseModule(Uint8List wasmBytes) {
  final deserializer = Deserializer(wasmBytes);
  return Module.deserialize(deserializer);
}

(ModulePrintSettings, List<String>) parseSettings(String dartCode) {
  const functionFilter = '// functionFilter=';
  const tableFilter = '// tableFilter=';
  const globalFilter = '// globalFilter=';
  const typeFilter = '// typeFilter=';
  const compilerOption = '// compilerOption=';

  final functionFilters = <RegExp>[];
  final tableFilters = <RegExp>[];
  final globalFilters = <RegExp>[];
  final typeFilters = <RegExp>[];
  final compilerOptions = <String>[];

  for (final line in dartCode.split('\n')) {
    for (final (prefix, regexpList) in [
      (functionFilter, functionFilters),
      (tableFilter, tableFilters),
      (globalFilter, globalFilters),
      (typeFilter, typeFilters),
    ]) {
      if (line.startsWith(prefix)) {
        final value = line.substring(prefix.length).trim();
        if (value.isNotEmpty) {
          regexpList.add(RegExp(value));
        }
      }
    }
    for (final (prefix, list) in [
      (compilerOption, compilerOptions),
    ]) {
      if (line.startsWith(prefix)) {
        final value = line.substring(prefix.length).trim();
        if (value.isNotEmpty) {
          list.add(value);
        }
      }
    }
  }
  return (
    ModulePrintSettings(
        functionFilters: functionFilters,
        tableFilters: tableFilters,
        globalFilters: globalFilters,
        typeFilters: typeFilters,
        preferMultiline: true,
        scrubAbsoluteUris: true,
        printInSortedOrder: true),
    compilerOptions
  );
}
