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

// ignore_for_file: uri_has_not_been_generated,undefined_identifier

/// Common platform independent benchmark infrastructure that can run
/// both on the VM and when compiled to JavaScript.
library common;

import 'dart:typed_data';

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

import 'temp/benchmarks.pb.dart';
import 'temp/datasets/google_message1/proto2/benchmark_message1_proto2.pb.dart'
    as p2;
import 'temp/datasets/google_message1/proto3/benchmark_message1_proto3.pb.dart'
    as p3;
import 'temp/datasets/google_message2/benchmark_message2.pb.dart';
import 'temp/datasets/google_message3/benchmark_message3.pb.dart';
import 'temp/datasets/google_message4/benchmark_message4.pb.dart';

/// Represents a dataset, a list of protobufs payloads, used for benchmarking.
/// All payloads are instances of the same message.
/// Datasets are loaded from BenchmarkDataset proto (see benchmark.proto).
class Dataset {
  final String name;

  /// Functions that can deserialize all payloads in this dataset.
  final Factories factories;

  /// List of packed payloads, which can be deserialized using [factories].
  /// Used for binary deserialization benchmarks.
  final List<Uint8List> packed = <Uint8List>[];

  /// Messages deserialized from [packed] and then serialized back into JSON.
  /// Used for JSON serialization benchmarks.
  final List<String> asJson = <String>[];

  /// Messages deserialized from [packed]. Used in serialization benchmarks.
  final List<GeneratedMessage> unpacked = <GeneratedMessage>[];

  /// Create [Dataset] from a [BenchmarkDataset] proto.
  factory Dataset.fromBinary(List<int> binary) {
    final dataSet = BenchmarkDataset.fromBuffer(binary);

    final factories = Factories.forMessage(dataSet.messageName);
    final ds = Dataset._(dataSet.name, factories);

    for (var payload in dataSet.payload) {
      final bytes = Uint8List.fromList(payload);
      final msg = factories.fromBuffer(bytes);
      ds.packed.add(bytes);
      ds.unpacked.add(msg);
      ds.asJson.add(msg.writeToJson());
    }

    return ds;
  }

  Dataset._(this.name, this.factories);
}

typedef dynamic FromBufferFactory(List<int> binary);
typedef dynamic FromJsonFactory(String json);

class Factories {
  final FromBufferFactory fromBuffer;
  final FromJsonFactory fromJson;

  static Factories forMessage(String name) =>
      _factories[name] ?? (throw "Unsupported message: ${name}");

  /// Mapping between [BenchmarkProto.messageName] and corresponding
  /// deserialization factories.
  static final _factories = {
    "benchmarks.proto2.GoogleMessage1": Factories._(
        fromBuffer: (List<int> binary) => p2.GoogleMessage1.fromBuffer(binary),
        fromJson: (String json) => p2.GoogleMessage1.fromJson(json)),
    "benchmarks.proto3.GoogleMessage1": Factories._(
        fromBuffer: (List<int> binary) => p3.GoogleMessage1.fromBuffer(binary),
        fromJson: (String json) => p3.GoogleMessage1.fromJson(json)),
    "benchmarks.proto2.GoogleMessage2": Factories._(
        fromBuffer: (List<int> binary) => GoogleMessage2.fromBuffer(binary),
        fromJson: (String json) => GoogleMessage2.fromJson(json)),
    "benchmarks.google_message3.GoogleMessage3": Factories._(
        fromBuffer: (List<int> binary) => GoogleMessage3.fromBuffer(binary),
        fromJson: (String json) => GoogleMessage3.fromJson(json)),
    "benchmarks.google_message4.GoogleMessage4": Factories._(
        fromBuffer: (List<int> binary) => GoogleMessage4.fromBuffer(binary),
        fromJson: (String json) => GoogleMessage4.fromJson(json)),
  };

  Factories._({this.fromBuffer, this.fromJson});
}

/// Base for all protobuf benchmarks.
abstract class _ProtobufBenchmark extends BenchmarkBase {
  final List<Dataset> datasets;

  _ProtobufBenchmark(this.datasets, String name) : super(name);
}

/// Binary deserialization benchmark.
class FromBinaryBenchmark extends _ProtobufBenchmark {
  FromBinaryBenchmark(datasets) : super(datasets, "FromBinary");

  void run() {
    for (var i = 0; i < datasets.length; i++) {
      final ds = datasets[i];
      final f = ds.factories.fromBuffer;
      for (var j = 0; j < ds.packed.length; j++) {
        f(ds.packed[j]);
      }
    }
  }
}

/// Binary serialization benchmark.
class ToBinaryBenchmark extends _ProtobufBenchmark {
  ToBinaryBenchmark(datasets) : super(datasets, "ToBinary");

  void run() {
    for (var i = 0; i < datasets.length; i++) {
      final ds = datasets[i];
      for (var j = 0; j < ds.unpacked.length; j++) {
        ds.unpacked[j].writeToBuffer();
      }
    }
  }
}

/// JSON deserialization benchmark.
class FromJsonBenchmark extends _ProtobufBenchmark {
  FromJsonBenchmark(datasets) : super(datasets, "FromJson");

  void run() {
    for (var i = 0; i < datasets.length; i++) {
      final ds = datasets[i];
      final f = ds.factories.fromJson;
      for (var j = 0; j < ds.asJson.length; j++) {
        f(ds.asJson[j]);
      }
    }
  }
}

/// JSON serialization benchmark.
class ToJsonBenchmark extends _ProtobufBenchmark {
  ToJsonBenchmark(datasets) : super(datasets, "ToJson");

  void run() {
    for (var i = 0; i < datasets.length; i++) {
      final ds = datasets[i];
      for (var j = 0; j < ds.unpacked.length; j++) {
        ds.unpacked[j].writeToJson();
      }
    }
  }
}
