# Copyright 2020 Google Inc. All rights reserved.
#
# Licensed 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.
"""Python benchmarking utilities.

Example usage:
  import google_benchmark as benchmark

  @benchmark.register
  def my_benchmark(state):
      ...  # Code executed outside `while` loop is not timed.

      while state:
        ...  # Code executed within `while` loop is timed.

  if __name__ == '__main__':
    benchmark.main()
"""
import atexit

from absl import app
from google_benchmark import _benchmark
from google_benchmark._benchmark import (
    Counter,
    kNanosecond,
    kMicrosecond,
    kMillisecond,
    kSecond,
    oNone,
    o1,
    oN,
    oNSquared,
    oNCubed,
    oLogN,
    oNLogN,
    oAuto,
    oLambda,
    State,
)


__all__ = [
    "register",
    "main",
    "Counter",
    "kNanosecond",
    "kMicrosecond",
    "kMillisecond",
    "kSecond",
    "oNone",
    "o1",
    "oN",
    "oNSquared",
    "oNCubed",
    "oLogN",
    "oNLogN",
    "oAuto",
    "oLambda",
    "State",
]

__version__ = "1.8.0"


class __OptionMaker:
    """A stateless class to collect benchmark options.

    Collect all decorator calls like @option.range(start=0, limit=1<<5).
    """

    class Options:
        """Pure data class to store options calls, along with the benchmarked function."""

        def __init__(self, func):
            self.func = func
            self.builder_calls = []

    @classmethod
    def make(cls, func_or_options):
        """Make Options from Options or the benchmarked function."""
        if isinstance(func_or_options, cls.Options):
            return func_or_options
        return cls.Options(func_or_options)

    def __getattr__(self, builder_name):
        """Append option call in the Options."""

        # The function that get returned on @option.range(start=0, limit=1<<5).
        def __builder_method(*args, **kwargs):

            # The decorator that get called, either with the benchmared function
            # or the previous Options
            def __decorator(func_or_options):
                options = self.make(func_or_options)
                options.builder_calls.append((builder_name, args, kwargs))
                # The decorator returns Options so it is not technically a decorator
                # and needs a final call to @register
                return options

            return __decorator

        return __builder_method


# Alias for nicer API.
# We have to instantiate an object, even if stateless, to be able to use __getattr__
# on option.range
option = __OptionMaker()


def register(undefined=None, *, name=None):
    """Register function for benchmarking."""
    if undefined is None:
        # Decorator is called without parenthesis so we return a decorator
        return lambda f: register(f, name=name)

    # We have either the function to benchmark (simple case) or an instance of Options
    # (@option._ case).
    options = __OptionMaker.make(undefined)

    if name is None:
        name = options.func.__name__

    # We register the benchmark and reproduce all the @option._ calls onto the
    # benchmark builder pattern
    benchmark = _benchmark.RegisterBenchmark(name, options.func)
    for name, args, kwargs in options.builder_calls[::-1]:
        getattr(benchmark, name)(*args, **kwargs)

    # return the benchmarked function because the decorator does not modify it
    return options.func


def _flags_parser(argv):
    argv = _benchmark.Initialize(argv)
    return app.parse_flags_with_usage(argv)


def _run_benchmarks(argv):
    if len(argv) > 1:
        raise app.UsageError("Too many command-line arguments.")
    return _benchmark.RunSpecifiedBenchmarks()


def main(argv=None):
    return app.run(_run_benchmarks, argv=argv, flags_parser=_flags_parser)


# Methods for use with custom main function.
initialize = _benchmark.Initialize
run_benchmarks = _benchmark.RunSpecifiedBenchmarks
atexit.register(_benchmark.ClearRegisteredBenchmarks)
