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

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

import 'package:benchmark_harness/benchmark_harness.dart';
import 'package:ffi/ffi.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 = nullptr; // 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 = Uint8List(0); // 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();
  }
}
