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