#!/usr/bin/env python3
# Copyright (c) 2024, the R8 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.

import argparse
import compiledump
import json
import os
import shutil
import subprocess
import sys

import utils
if utils.is_bot():
    import upload_benchmark_data_to_google_storage

# A collection of benchmarks that should be run on the perf bot.
EXTERNAL_BENCHMARKS = {
    'ChromeApp': {
        'targets': ['r8-full']
    },
    'CraneApp': {
        'targets': ['r8-full']
    },
    'HelloWorld': {
        'targets': ['d8']
    },
    'HelloWorldNoLib': {
        'targets': ['d8']
    },
    'HelloWorldCf': {
        'targets': ['d8']
    },
    'HelloWorldCfNoLib': {
        'targets': ['d8']
    },
    'JetLaggedApp': {
        'targets': ['r8-full']
    },
    'JetNewsApp': {
        'targets': ['r8-full']
    },
    'JetCasterApp': {
        'targets': ['r8-full']
    },
    'JetChatApp': {
        'targets': ['r8-full']
    },
    'JetSnackApp': {
        'targets': ['r8-full']
    },
    'NowInAndroidApp': {
        'targets': ['d8', 'r8-full']
    },
    'NowInAndroidAppIncremental': {
        'targets': ['d8'],
        'subBenchmarks': {
            'd8': ['Dex', 'Merge']
        }
    },
    'NowInAndroidAppNoJ$': {
        'targets': ['d8']
    },
    'NowInAndroidAppNoJ$Incremental': {
        'targets': ['d8'],
        'subBenchmarks': {
            'd8': ['Dex']
        }
    },
    'OwlApp': {
        'targets': ['r8-full']
    },
    'R8': {
        'targets': ['retrace']
    },
    'ReplyApp': {
        'targets': ['r8-full']
    },
    'TiviApp': {
        'targets': ['r8-full']
    },
}
# A collection of internal benchmarks that should be run on the internal bot.
INTERNAL_BENCHMARKS = {
    'SystemUIApp': {'targets': ['r8-full']},
}
# A collection of benchmarks that should not be run on the bots, but can be used
# for running locally.
LOCAL_BENCHMARKS = {
    'SystemUIAppTreeShaking': {'targets': ['r8-full']}}
ALL_BENCHMARKS = {}
ALL_BENCHMARKS.update(EXTERNAL_BENCHMARKS)
ALL_BENCHMARKS.update(INTERNAL_BENCHMARKS)
ALL_BENCHMARKS.update(LOCAL_BENCHMARKS)
BUCKET = "r8-perf-results"
SAMPLE_BENCHMARK_RESULT_JSON = {
    'benchmark_name': '<benchmark_name>',
    'results': [{
        'code_size': 0,
        'runtime': 0
    }]
}


# Result structure on cloud storage
# gs://bucket/benchmark_results/APP/TARGET/GIT_HASH/result.json
#                                                   meta
# where results simply contains the result lines and
# meta contains information about the execution (machine)
def ParseOptions():
    result = argparse.ArgumentParser()
    result.add_argument('--benchmark',
                        help='Specific benchmark(s) to measure.',
                        action='append')
    result.add_argument('--internal',
                        help='Run internal benchmarks.',
                        action='store_true',
                        default=False)
    result.add_argument('--iterations',
                        help='How many times run_benchmark is run.',
                        type=int,
                        default=1)
    result.add_argument('--iterations-inner',
                        help='How many iterations to run inside run_benchmark.',
                        type=int,
                        default=10)
    result.add_argument('--outdir',
                        help='Output directory for running locally.')
    result.add_argument('--skip-if-output-exists',
                        help='Skip if output exists.',
                        action='store_true',
                        default=False)
    result.add_argument(
        '--target',
        help='Specific target to run on.',
        choices=['d8', 'r8-full', 'r8-force', 'r8-compat', 'retrace'])
    result.add_argument('--verbose',
                        help='To enable verbose logging.',
                        action='store_true',
                        default=False)
    result.add_argument('--version',
                        '-v',
                        help='Use R8 hash for the run (default local build)')
    result.add_argument('--version-jar',
                        help='The r8lib.jar for the given version.')
    options, args = result.parse_known_args()
    if options.benchmark:
        options.benchmarks = options.benchmark
    elif options.internal:
        options.benchmarks = INTERNAL_BENCHMARKS.keys()
    else:
        options.benchmarks = EXTERNAL_BENCHMARKS.keys()
    options.quiet = not options.verbose
    del options.benchmark
    return options, args


def Build(options):
    utils.Print('Building', quiet=options.quiet)
    target = options.target or 'r8-full'
    build_cmd = GetRunCmd('N/A', target, options, ['--iterations', '0'])
    subprocess.check_call(build_cmd)


def GetRunCmd(benchmark, target, options, args, r8jar=None):
    base_cmd = [
        'tools/run_benchmark.py', '--benchmark', benchmark, '--target', target
    ]
    if options.verbose:
        base_cmd.append('--verbose')
    if options.version and r8jar is not None:
        base_cmd.extend(
            ['--version', options.version, '--version-jar', r8jar, '--nolib'])
    return base_cmd + args


def MergeBenchmarkResultJsonFiles(benchmark_result_json_files):
    merged_benchmark_result_json = None
    for benchmark_result_json_file in benchmark_result_json_files:
        benchmark_result_json = ParseBenchmarkResultJsonFile(
            benchmark_result_json_file)
        if merged_benchmark_result_json is None:
            merged_benchmark_result_json = benchmark_result_json
        else:
            MergeBenchmarkResultJsonFile(merged_benchmark_result_json,
                                         benchmark_result_json)
    return merged_benchmark_result_json


def MergeBenchmarkResultJsonFile(merged_benchmark_result_json,
                                 benchmark_result_json):
    assert benchmark_result_json.keys() == SAMPLE_BENCHMARK_RESULT_JSON.keys()
    assert merged_benchmark_result_json[
        'benchmark_name'] == benchmark_result_json['benchmark_name']
    merged_benchmark_result_json['results'].extend(
        benchmark_result_json['results'])


def ParseBenchmarkResultJsonFile(result_json_file):
    with open(result_json_file, 'r') as f:
        lines = f.readlines()
        return json.loads(''.join(lines))


def GetArtifactLocation(benchmark, target, version, filename):
    version_or_head = version or utils.get_HEAD_sha1()
    return f'{benchmark}/{target}/{version_or_head}/{filename}'


def GetGSLocation(filename, bucket=BUCKET):
    return f'gs://{bucket}/{filename}'


def ArchiveBenchmarkResult(benchmark, target, benchmark_result_json_files,
                           options, temp):
    result_file = os.path.join(temp, 'result_file')
    with open(result_file, 'w') as f:
        json.dump(MergeBenchmarkResultJsonFiles(benchmark_result_json_files), f)
    ArchiveOutputFile(result_file,
                      GetArtifactLocation(benchmark, target, options.version,
                                          'result.json'),
                      outdir=options.outdir)


def ArchiveOutputFile(file, dest, bucket=BUCKET, header=None, outdir=None):
    if outdir:
        dest_in_outdir = os.path.join(outdir, dest)
        os.makedirs(os.path.dirname(dest_in_outdir), exist_ok=True)
        shutil.copyfile(file, dest_in_outdir)
    else:
        utils.upload_file_to_cloud_storage(file,
                                           GetGSLocation(dest, bucket=bucket),
                                           header=header)


# Usage with historic_run.py:
# ./tools/historic_run.py
#     --cmd "perf.py --skip-if-output-exists --version"
#     --timeout -1
#     --top 3373fd18453835bf49bff9f02523a507a2ebf317
#     --bottom 7486f01e0622cb5935b77a92b59ddf1ca8dbd2e2
def main():
    options, args = ParseOptions()
    Build(options)
    any_failed = False
    with utils.TempDir() as temp:
        if options.version:
            # Download r8.jar once instead of once per run_benchmark.py invocation.
            download_options = argparse.Namespace(no_build=True, nolib=True)
            r8jar = options.version_jar or compiledump.download_distribution(
                options.version, download_options, temp)
        else:
            r8jar = None
        for benchmark in options.benchmarks:
            benchmark_info = ALL_BENCHMARKS[benchmark]
            targets = [options.target
                      ] if options.target else benchmark_info['targets']
            for target in targets:
                sub_benchmarks = benchmark_info.get('subBenchmarks', {})
                sub_benchmarks_for_target = sub_benchmarks.get(target, [])

                if options.skip_if_output_exists:
                    assert len(sub_benchmarks_for_target) == 0, 'Unimplemented'
                    if options.outdir:
                        raise NotImplementedError
                    output = GetGSLocation(
                        GetArtifactLocation(benchmark, target, options.version,
                                            'result.json'))
                    if utils.cloud_storage_exists(output):
                        print(f'Skipping run, {output} already exists.')
                        continue

                # Run benchmark.
                if sub_benchmarks_for_target:
                    benchmark_result_json_files = {}
                    for sub_benchmark in sub_benchmarks_for_target:
                        benchmark_result_json_files[sub_benchmark] = []
                else:
                    benchmark_result_json_files = []

                # Prepare out dir.
                temp_benchmark_target = os.path.join(temp, benchmark, target)
                os.makedirs(temp_benchmark_target)

                failed = False
                for i in range(options.iterations):
                    utils.Print(
                        f'Benchmarking {benchmark} ({i+1}/{options.iterations})',
                        quiet=options.quiet)
                    if sub_benchmarks_for_target:
                        benchmark_result_file = os.path.join(
                            temp_benchmark_target, f'result_{i}')
                        os.makedirs(benchmark_result_file)
                    else:
                        benchmark_result_file = os.path.join(
                            temp_benchmark_target, f'result_file_{i}')
                    iteration_cmd = GetRunCmd(benchmark, target, options, [
                        '--iterations',
                        str(options.iterations_inner), '--output',
                        benchmark_result_file, '--no-build'
                    ], r8jar)
                    try:
                        subprocess.check_call(iteration_cmd)
                        if sub_benchmarks_for_target:
                            for sub_benchmark in sub_benchmarks_for_target:
                                sub_benchmark_result_file = os.path.join(
                                    benchmark_result_file,
                                    benchmark + sub_benchmark)
                                benchmark_result_json_files[
                                    sub_benchmark].append(
                                        sub_benchmark_result_file)
                        else:
                            benchmark_result_json_files.append(
                                benchmark_result_file)
                    except subprocess.CalledProcessError as e:
                        failed = True
                        any_failed = True
                        break

                if failed:
                    continue

                # Merge results and write output.
                if sub_benchmarks_for_target:
                    for sub_benchmark in sub_benchmarks_for_target:
                        ArchiveBenchmarkResult(
                            benchmark + sub_benchmark, target,
                            benchmark_result_json_files[sub_benchmark], options,
                            temp)
                else:
                    ArchiveBenchmarkResult(benchmark, target,
                                           benchmark_result_json_files, options,
                                           temp)

                # Write metadata.
                if utils.is_bot():
                    meta_file = os.path.join(temp, "meta")
                    with open(meta_file, 'w') as f:
                        f.write("Produced by: " +
                                os.environ.get('SWARMING_BOT_ID'))
                    ArchiveOutputFile(meta_file,
                                      GetArtifactLocation(
                                          benchmark, target, options.version,
                                          'meta'),
                                      outdir=options.outdir)

    # Only upload benchmark data when running on the perf bot.
    if utils.is_bot() and not options.internal:
        upload_benchmark_data_to_google_storage.run_bucket()

    if any_failed:
        return 1


if __name__ == '__main__':
    sys.exit(main())
