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