// Copyright (c) 2024, 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:js_interop';
import 'dart:convert';
import 'dart:typed_data';

import 'package:benchmark_harness/benchmark_harness.dart';

void main(List<String> args) {
  final smallDartString = 'a' * 10;
  final mediumDartString = 'a' * 1024;
  final largeDartString = 'a' * 1024 * 1024;

  final smallJsString = smallDartString.toJS;
  final mediumJsString = mediumDartString.toJS;
  final largeJsString = largeDartString.toJS;

  final smallDartBytes = utf8.encode(smallDartString);
  final mediumDartBytes = utf8.encode(mediumDartString);
  final largeDartBytes = utf8.encode(largeDartString);

  final smallJsBytes = smallDartBytes.toJS;
  final mediumJsBytes = mediumDartBytes.toJS;
  final largeJsBytes = largeDartBytes.toJS;

  WasmDataTransferFromBrowserString(smallJsString, '10').report();
  WasmDataTransferFromBrowserBytes(smallJsBytes, '10').report();
  WasmDataTransferToBrowserString(smallDartString, '10').report();
  WasmDataTransferToBrowserBytes(smallDartBytes, '10').report();

  WasmDataTransferFromBrowserString(mediumJsString, '1KB').report();
  WasmDataTransferFromBrowserBytes(mediumJsBytes, '1KB').report();
  WasmDataTransferToBrowserString(mediumDartString, '1KB').report();
  WasmDataTransferToBrowserBytes(mediumDartBytes, '1KB').report();

  WasmDataTransferFromBrowserString(largeJsString, '1MB').report();
  WasmDataTransferFromBrowserBytes(largeJsBytes, '1MB').report();
  WasmDataTransferToBrowserString(largeDartString, '1MB').report();
  WasmDataTransferToBrowserBytes(largeDartBytes, '1MB').report();
}

class PrintEmitter implements ScoreEmitter {
  const PrintEmitter();

  @override
  void emit(String testName, double value) {
    print('$testName(RunTimeRaw): $value us.');
  }
}

abstract class Benchmark extends BenchmarkBase {
  Benchmark(super.name) : super(emitter: const PrintEmitter());

  @override
  void exercise() {
    // To avoid using the super class's implementation which runs for 10
    // iterations thereby making the measured time off by 10x.
    run();
  }
}

class WasmDataTransferFromBrowserString extends Benchmark {
  final JSString jsonString;

  WasmDataTransferFromBrowserString(this.jsonString, String subName)
    : super('WasmDataTransfer.FromBrowserString.$subName');

  @override
  void run() {
    // We don't expose a way to convert JS string to Dart string (as string
    // implementation in Dart is implementation specific - we may even use JS
    // strings).
    //
    // But currently we use internal one/two byte strings and using string
    // interpolation forces transfer of string to be internal string.
    //
    // Though string interpolation also causes other work (it convers JS string
    // to dart and then allocates new string for interpolation result)
    use('a${jsonString.toDart}');
  }
}

class WasmDataTransferFromBrowserBytes extends Benchmark {
  final JSUint8Array bytes;

  WasmDataTransferFromBrowserBytes(this.bytes, String subName)
    : super('WasmDataTransfer.FromBrowserBytes.$subName');

  @override
  void run() {
    use(Uint8List.fromList(bytes.toDart));
  }
}

class WasmDataTransferToBrowserString extends Benchmark {
  final String string;

  WasmDataTransferToBrowserString(this.string, String subName)
    : super('WasmDataTransfer.ToBrowserString.$subName');

  @override
  void run() {
    use(string.toJS);
  }
}

class WasmDataTransferToBrowserBytes extends Benchmark {
  final Uint8List bytes;

  WasmDataTransferToBrowserBytes(this.bytes, String subName)
    : super('WasmDataTransfer.ToBrowserBytes.$subName');

  @override
  void run() {
    use(bytes.toJS);
  }
}

var globalSink;
void use<T>(T a) {
  globalSink = a;
  if (kFalse) print(globalSink);
}

final kTrue = int.parse('1') == 1;
final kFalse = !kTrue;
