# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""A microbenchmark for measuring performance of coders.

This runs a sequence of encode-decode operations on random inputs
to collect performance of various coders.

To evaluate coders performance we approximate the behavior
how the coders are used in PCollections: we encode and decode
a list of elements. An element can be a string, a list of integers,
a windowed value, or any other object we want a coder to process.

Run as:
  python -m apache_beam.tools.coders_microbenchmark

"""

# pytype: skip-file

import argparse
import logging
import random
import re
import string
import sys

import apache_beam as beam
from apache_beam.coders import coder_impl
from apache_beam.coders import coders
from apache_beam.coders import coders_test_common
from apache_beam.coders import proto2_coder_test_messages_pb2 as test_message
from apache_beam.coders import row_coder
from apache_beam.coders import typecoders
from apache_beam.tools import utils
from apache_beam.transforms import window
from apache_beam.typehints import trivial_inference
from apache_beam.typehints.pandas_type_compatibility import DataFrameBatchConverterDropIndex
from apache_beam.utils import windowed_value


def coder_benchmark_factory(coder, generate_fn):
  """Creates a benchmark that encodes and decodes a list of elements.

  Args:
    coder: coder to use to encode an element.
    generate_fn: a callable that generates an element.
  """
  class CoderBenchmark(object):
    def __init__(self, num_elements_per_benchmark):
      self._coder = coders.IterableCoder(coder)
      self._list = [generate_fn() for _ in range(num_elements_per_benchmark)]

    def __call__(self):
      # Calling coder operations on a single element at a time may incur
      # unrelevant overhead. To compensate, we use a list elements.
      _ = self._coder.decode(self._coder.encode(self._list))

  CoderBenchmark.__name__ = "%s, %s" % (generate_fn.__name__, str(coder))

  return CoderBenchmark


def batch_row_coder_benchmark_factory(generate_fn, use_batch):
  """Creates a benchmark that encodes and decodes a list of elements.

  Args:
    coder: coder to use to encode an element.
    generate_fn: a callable that generates an element.
  """
  class CoderBenchmark(object):
    def __init__(self, num_elements_per_benchmark):
      self._use_batch = use_batch
      row_instance = generate_fn()
      row_type = trivial_inference.instance_to_type(row_instance)
      self._row_coder = get_row_coder(row_instance)
      self._batch_converter = DataFrameBatchConverterDropIndex(row_type)
      self._seq_coder = coders.IterableCoder(self._row_coder)
      self._data = self._batch_converter.produce_batch(
          [generate_fn() for _ in range(num_elements_per_benchmark)])

    def __call__(self):
      if self._use_batch:
        impl = self._row_coder.get_impl()
        columnar = {
            col: self._data[col].to_numpy()
            for col in self._data.columns
        }
        output_stream = coder_impl.create_OutputStream()
        impl.encode_batch_to_stream(columnar, output_stream)
        impl.decode_batch_from_stream(
            columnar, coder_impl.create_InputStream(output_stream.get()))

      else:
        # Calling coder operations on a single element at a time may incur
        # unrelevant overhead. To compensate, we use a list elements.
        self._batch_converter.produce_batch(
            self._seq_coder.decode(
                self._seq_coder.encode(
                    self._batch_converter.explode_batch(self._data))))

  CoderBenchmark.__name__ = "%s, BatchRowCoder%s" % (
      generate_fn.__name__, use_batch)

  return CoderBenchmark


def small_int():
  return random.randint(0, 127)


def large_int():
  return random.randint(sys.maxsize >> 2, sys.maxsize)


def random_string(length):
  return ''.join(
      random.choice(string.ascii_letters + string.digits)
      for _ in range(length))


def small_string():
  return random_string(4)


def large_string():
  return random_string(100)


def list_int(size):
  return [small_int() for _ in range(size)]


def dict_int_int(size):
  return {i: i for i in list_int(size)}


def small_list():
  return list_int(10)


def large_list():
  # Bool is the last item in FastPrimitiveCoders before pickle.
  return [bool(k) for k in list_int(1000)]


def small_tuple():
  # Benchmark a common case of 2-element tuples.
  return tuple(list_int(2))


def large_tuple():
  return tuple(large_list())


def small_dict():
  return {i: i for i in small_list()}


def large_dict():
  return {i: i for i in large_list()}


def large_iterable():
  yield 'a' * coders.coder_impl.SequenceCoderImpl._DEFAULT_BUFFER_SIZE
  for k in range(1000):
    yield k


def random_message_with_map(size):
  message = test_message.MessageWithMap()
  keys = list_int(size)
  random.shuffle(keys)
  for key in keys:
    message.field1[str(key)].field1 = small_string()
  return message


def small_message_with_map():
  return random_message_with_map(5)


def large_message_with_map():
  return random_message_with_map(20)


def globally_windowed_value():
  return windowed_value.WindowedValue(
      value=small_int(), timestamp=12345678, windows=(window.GlobalWindow(), ))


def random_windowed_value(num_windows):
  return windowed_value.WindowedValue(
      value=small_int(),
      timestamp=12345678,
      windows=tuple(
          window.IntervalWindow(i * 10, i * 10 + small_int())
          for i in range(num_windows)))


def wv_with_one_window():
  return random_windowed_value(num_windows=1)


def wv_with_multiple_windows():
  return random_windowed_value(num_windows=32)


def tiny_row():
  return beam.Row(int_value=1)


def large_row():
  return beam.Row(**{f'int_{ix}': ix for ix in range(20)})


def nullable_row():
  return beam.Row(**{f'int_{ix}': ix if ix % 2 else None for ix in range(20)})


def diverse_row():
  return beam.Row(
      int_value=1,
      float_value=3.14159,
      str_value='beam',
      row_value=beam.Row(int_value=2, float_value=2.718281828))


def get_row_coder(row_instance):
  coder = typecoders.registry.get_coder(
      trivial_inference.instance_to_type(row_instance))
  assert isinstance(coder, row_coder.RowCoder)
  return coder


def row_coder_benchmark_factory(generate_fn):
  return coder_benchmark_factory(get_row_coder(generate_fn()), generate_fn)


def importable_named_tuple():
  return [coders_test_common.MyTypedNamedTuple('a', i) for i in range(1000)]


def run_coder_benchmarks(
    num_runs, input_size, seed, verbose, filter_regex='.*'):
  random.seed(seed)

  # TODO(https://github.com/apache/beam/issues/18788): Pick coders using type
  # hints, for example:
  # tuple_coder = typecoders.registry.get_coder(typing.Tuple[int, ...])
  benchmarks = [
      coder_benchmark_factory(coders.FastPrimitivesCoder(), small_int),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), large_int),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), small_string),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), large_string),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), small_list),
      coder_benchmark_factory(
          coders.IterableCoder(coders.FastPrimitivesCoder()), small_list),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), large_list),
      coder_benchmark_factory(
          coders.IterableCoder(coders.FastPrimitivesCoder()), large_list),
      coder_benchmark_factory(
          coders.IterableCoder(coders.FastPrimitivesCoder()), large_iterable),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), small_tuple),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), large_tuple),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), small_dict),
      coder_benchmark_factory(coders.FastPrimitivesCoder(), large_dict),
      coder_benchmark_factory(
          coders.ProtoCoder(test_message.MessageWithMap),
          small_message_with_map),
      coder_benchmark_factory(
          coders.ProtoCoder(test_message.MessageWithMap),
          large_message_with_map),
      coder_benchmark_factory(
          coders.DeterministicProtoCoder(test_message.MessageWithMap),
          small_message_with_map),
      coder_benchmark_factory(
          coders.DeterministicProtoCoder(test_message.MessageWithMap),
          large_message_with_map),
      coder_benchmark_factory(
          coders.WindowedValueCoder(coders.FastPrimitivesCoder()),
          wv_with_one_window),
      coder_benchmark_factory(
          coders.WindowedValueCoder(
              coders.FastPrimitivesCoder(), coders.IntervalWindowCoder()),
          wv_with_multiple_windows),
      coder_benchmark_factory(
          coders.WindowedValueCoder(
              coders.FastPrimitivesCoder(), coders.GlobalWindowCoder()),
          globally_windowed_value),
      coder_benchmark_factory(
          coders.LengthPrefixCoder(coders.FastPrimitivesCoder()), small_int),
      row_coder_benchmark_factory(tiny_row),
      row_coder_benchmark_factory(large_row),
      row_coder_benchmark_factory(nullable_row),
      row_coder_benchmark_factory(diverse_row),
      batch_row_coder_benchmark_factory(tiny_row, False),
      batch_row_coder_benchmark_factory(tiny_row, True),
      batch_row_coder_benchmark_factory(large_row, False),
      batch_row_coder_benchmark_factory(large_row, True),
      batch_row_coder_benchmark_factory(nullable_row, False),
      batch_row_coder_benchmark_factory(nullable_row, True),
      batch_row_coder_benchmark_factory(diverse_row, False),
      batch_row_coder_benchmark_factory(diverse_row, True),
      coder_benchmark_factory(
          coders.IterableCoder(
              coders.FastPrimitivesCoder().as_deterministic_coder(
                  step_label="step")),
          importable_named_tuple),
  ]

  suite = [
      utils.BenchmarkConfig(b, input_size, num_runs) for b in benchmarks
      if re.search(filter_regex, b.__name__, flags=re.I)
  ]
  utils.run_benchmarks(suite, verbose=verbose)


if __name__ == "__main__":
  logging.basicConfig()

  parser = argparse.ArgumentParser()
  parser.add_argument('--filter', default='.*')
  parser.add_argument('--num_runs', default=20, type=int)
  parser.add_argument('--num_elements_per_benchmark', default=1000, type=int)
  parser.add_argument('--seed', default=42, type=int)
  options = parser.parse_args()

  utils.check_compiled("apache_beam.coders.coder_impl")

  num_runs = 20
  num_elements_per_benchmark = 1000
  seed = 42  # Fix the seed for better consistency

  run_coder_benchmarks(
      options.num_runs,
      options.num_elements_per_benchmark,
      options.seed,
      verbose=True,
      filter_regex=options.filter)
