// Copyright (c) 2019, 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.

// Macro-benchmark for ffi with boringssl.

// @dart=2.9

import 'dart:convert';
import 'dart:ffi';
import 'dart:typed_data';

import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:ffi/ffi.dart';

import 'calloc.dart';
import 'digest.dart';
import 'types.dart';

//
// BoringSSL functions
//

Uint8List inventData(int length) {
  final result = Uint8List(length);
  for (int i = 0; i < length; i++) {
    result[i] = i % 256;
  }
  return result;
}

Uint8List toUint8List(Pointer<Bytes> bytes, int length) {
  final result = Uint8List(length);
  final uint8bytes = bytes.asUint8Pointer();
  for (int i = 0; i < length; i++) {
    result[i] = uint8bytes[i];
  }
  return result;
}

void copyFromUint8ListToTarget(Uint8List source, Pointer<Data> target) {
  final int length = source.length;
  final uint8target = target.asUint8Pointer();
  for (int i = 0; i < length; i++) {
    uint8target[i] = source[i];
  }
}

String hash(Pointer<Data> data, int length, Pointer<EVP_MD> hashAlgorithm) {
  final context = EVP_MD_CTX_new();
  EVP_DigestInit(context, hashAlgorithm);
  EVP_DigestUpdate(context, data, length);
  final int resultSize = EVP_MD_CTX_size(context);
  final Pointer<Bytes> result = calloc<Uint8>(resultSize).cast();
  EVP_DigestFinal(context, result, nullptr);
  EVP_MD_CTX_free(context);
  final String hash = base64Encode(toUint8List(result, resultSize));
  calloc.free(result);
  return hash;
}

//
// Benchmark fixtures.
//

// Number of repeats: 1 && Length in bytes: 10000000
//  * CPU: Intel(R) Xeon(R) Gold 6154
//    * Architecture: x64
//      * 23000 - 52000000 us (without optimizations)
//      * 23000 - 30000 us (with optimizations)
const int L = 1000; // Length of data in bytes.

final hashAlgorithm = EVP_sha512();

// Hash of generated data of `L` bytes with `hashAlgorithm`.
const String expectedHash =
    'bNLtqb+cBZcSkCmwBUuB5DP2uLe0madetwXv10usGUFJg1sdGhTEi+aW5NWIRW1RKiLq56obV74rVurn014Iyw==';

/// This benchmark runs a digest algorithm on data residing in C memory.
///
/// This benchmark is intended as macro benchmark with a realistic workload.
class DigestCMemory extends BenchmarkBase {
  DigestCMemory() : super('FfiBoringssl.DigestCMemory');

  Pointer<Data> data; // Data in C memory that we want to digest.

  @override
  void setup() {
    data = calloc<Uint8>(L).cast();
    copyFromUint8ListToTarget(inventData(L), data);
    hash(data, L, hashAlgorithm);
  }

  @override
  void teardown() {
    calloc.free(data);
  }

  @override
  void run() {
    final String result = hash(data, L, hashAlgorithm);
    if (result != expectedHash) {
      throw Exception('$name: Unexpected result: $result');
    }
  }
}

/// This benchmark runs a digest algorithm on data residing in Dart memory.
///
/// This benchmark is intended as macro benchmark with a realistic workload.
class DigestDartMemory extends BenchmarkBase {
  DigestDartMemory() : super('FfiBoringssl.DigestDartMemory');

  Uint8List data; // Data in C memory that we want to digest.

  @override
  void setup() {
    data = inventData(L);
    final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
    copyFromUint8ListToTarget(data, dataInC);
    hash(dataInC, L, hashAlgorithm);
    calloc.free(dataInC);
  }

  @override
  void teardown() {}

  @override
  void run() {
    final Pointer<Data> dataInC = calloc<Uint8>(L).cast();
    copyFromUint8ListToTarget(data, dataInC);
    final String result = hash(dataInC, L, hashAlgorithm);
    calloc.free(dataInC);
    if (result != expectedHash) {
      throw Exception('$name: Unexpected result: $result');
    }
  }
}

//
// Main driver.
//

void main() {
  final benchmarks = [
    () => DigestCMemory(),
    () => DigestDartMemory(),
  ];
  for (final benchmark in benchmarks) {
    benchmark().report();
  }
}
