#!/usr/bin/python3
#
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_restricted_traces.py:
#   Generates integration code for the restricted trace tests.

import getpass
import glob
import fnmatch
import json
import os
import sys

GNI_TEMPLATE = """\
# GENERATED FILE - DO NOT EDIT.
# Generated by {script_name} using data from {data_source_name}
#
# Copyright 2020 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# A list of all restricted trace tests, paired with their context.
# Can be consumed by tests/BUILD.gn.

angle_restricted_traces = [
{test_list}
]
"""

HEADER_TEMPLATE = """\
// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {filename}: Types and enumerations for trace tests.

#ifndef ANGLE_RESTRICTED_TRACES_AUTOGEN_H_
#define ANGLE_RESTRICTED_TRACES_AUTOGEN_H_

#include <cstdint>
#include <vector>
#include <KHR/khrplatform.h>
#include <EGL/egl.h>

#include "restricted_traces_export.h"

namespace trace_angle
{{
using GenericProc = void (*)();
using LoadProc    = GenericProc(KHRONOS_APIENTRY *)(const char *);
ANGLE_TRACE_LOADER_EXPORT void LoadEGL(LoadProc loadProc);
ANGLE_TRACE_LOADER_EXPORT void LoadGLES(LoadProc loadProc);
}}  // namespace trace_angle

namespace angle
{{
static constexpr size_t kTraceInfoMaxNameLen = 32;

static constexpr uint32_t kDefaultReplayContextClientMajorVersion = 3;
static constexpr uint32_t kDefaultReplayContextClientMinorVersion = 1;
static constexpr uint32_t kDefaultReplayDrawSurfaceColorSpace = EGL_COLORSPACE_LINEAR;

struct TraceInfo
{{
    uint32_t contextClientMajorVersion;
    uint32_t contextClientMinorVersion;
    uint32_t startFrame;
    uint32_t endFrame;
    uint32_t drawSurfaceWidth;
    uint32_t drawSurfaceHeight;
    uint32_t drawSurfaceColorSpace;
    char name[kTraceInfoMaxNameLen];
}};

ANGLE_TRACE_EXPORT const TraceInfo &GetTraceInfo(const char *traceName);
}}  // namespace angle

#endif  // ANGLE_RESTRICTED_TRACES_AUTOGEN_H_
"""

SOURCE_TEMPLATE = """\
// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}
//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// {filename}: Types and enumerations for trace tests.

#include "{filename}.h"

#include "common/PackedEnums.h"
#include "common/system_utils.h"

{trace_includes}

namespace angle
{{
namespace
{{
constexpr size_t kNumTraces = {num_traces};
struct TracePair
{{
    const char name[kTraceInfoMaxNameLen];
    TraceInfo info;
}};
constexpr TracePair kTraceInfos[kNumTraces] = {{
{trace_infos}
}};
}}

const TraceInfo &GetTraceInfo(const char *traceName)
{{
    // Could be improved using std::lower_bound.
    for (const TracePair &tracePair : kTraceInfos)
    {{
        if (strncmp(tracePair.name, traceName, kTraceInfoMaxNameLen) == 0)
        {{
            return tracePair.info;
        }}
    }}
    UNREACHABLE();
    return kTraceInfos[0].info;
}}
}}  // namespace angle
"""

CIPD_TRACE_PREFIX = 'angle/traces'
EXPERIMENTAL_CIPD_PREFIX = 'experimental/google.com/%s/angle/traces'
DEPS_PATH = '../../../DEPS'
DEPS_START = '# === ANGLE Restricted Trace Generated Code Start ==='
DEPS_END = '# === ANGLE Restricted Trace Generated Code End ==='
DEPS_TEMPLATE = """\
  'src/tests/restricted_traces/{trace}': {{
      'packages': [
        {{
            'package': '{trace_prefix}/{trace}',
            'version': 'version:{version}',
        }},
      ],
      'dep_type': 'cipd',
      'condition': 'checkout_angle_restricted_traces',
  }},
"""


def reject_duplicate_keys(pairs):
    found_keys = {}
    for key, value in pairs:
        if key in found_keys:
            raise ValueError("duplicate key: %r" % (key,))
        else:
            found_keys[key] = value
    return found_keys


# TODO(http://anglebug.com/5878): Revert back to non-autogen'ed file names for the angledata.gz.
def get_angledata_filename(trace):
    angledata_files = glob.glob('%s/%s*angledata.gz' % (trace, trace))
    assert len(angledata_files) == 1, "Trace '%s' has %d angledata.gz files" % (
        trace, len(angledata_files))
    return angledata_files[0].replace('\\', '/')


def gen_gni(traces, gni_file, format_args):
    test_list = []
    for trace in traces:
        context = get_context(trace)
        angledata_file = get_angledata_filename(trace)
        with open('%s/%s_capture_context%s_files.txt' % (trace, trace, context)) as f:
            files = f.readlines()
            f.close()
        files = ['"%s/%s"' % (trace, file.strip()) for file in files]
        test_list += ['["%s", %s, [%s], "%s"]' % (trace, context, ','.join(files), angledata_file)]

    format_args['test_list'] = ',\n'.join(test_list)
    gni_data = GNI_TEMPLATE.format(**format_args)
    with open(gni_file, "w") as out_file:
        out_file.write(gni_data)
    return True


def contains_string(trace, string):
    """Determines if the trace contains a string"""
    for file in os.listdir(trace):
        if fnmatch.fnmatch(file, '*.h'):
            with open(os.path.join(trace, file)) as f:
                if string in f.read():
                    return True
    return False


def contains_context_version(trace):
    """Determines if the trace contains the major/minor context version"""
    return contains_string(trace, 'kReplayContextClientMajorVersion')


def contains_colorspace(trace):
    """Determines if the trace contains an EGL surface color space"""
    return contains_string(trace, 'kReplayDrawSurfaceColorSpace')


def get_trace_info(trace):
    # Some traces don't contain major/minor version, so use defaults
    info = []
    if contains_context_version(trace):
        info += [
            f'{trace}::kReplayContextClientMajorVersion',
            f'{trace}::kReplayContextClientMinorVersion'
        ]
    else:
        info += [
            'kDefaultReplayContextClientMajorVersion', 'kDefaultReplayContextClientMinorVersion'
        ]

    info += [
        f'{trace}::kReplayFrameStart', f'{trace}::kReplayFrameEnd',
        f'{trace}::kReplayDrawSurfaceWidth', f'{trace}::kReplayDrawSurfaceHeight'
    ]

    if contains_colorspace(trace):
        info += [f'{trace}::kReplayDrawSurfaceColorSpace']
    else:
        info += ['kDefaultReplayDrawSurfaceColorSpace']

    info += [f'"{trace}"']

    return ", ".join(info)


def get_context(trace):
    """Returns the context number used by trace txt file"""
    for file in os.listdir(trace):
        # Load up the only header present for each trace
        if fnmatch.fnmatch(file, '*.txt'):
            # Strip the extension to isolate the context by scanning
            # for numbers leading up to the last one, i.e.:
            #     app_capture_context123_files.txt
            #                          ^^
            #                  start---||---end
            start = len(file) - 11
            end = start + 1
            while file[start - 1].isdigit():
                start -= 1
            context = file[start:end]
            assert context.isnumeric(), 'Failed to find trace context number'
            return context


def get_header_name(trace):
    return '%s/%s_capture_context%s.h' % (trace, trace, get_context(trace))


def get_source_name(trace):
    return '%s/%s_capture_context%s.cpp' % (trace, trace, get_context(trace))


def gen_header(header_file, format_args):
    header_data = HEADER_TEMPLATE.format(**format_args)
    with open(header_file, "w") as out_file:
        out_file.write(header_data)
    return True


def gen_source(source_file, format_args):
    source_data = SOURCE_TEMPLATE.format(**format_args)
    with open(source_file, "w") as out_file:
        out_file.write(source_data)
    return True


def gen_git_ignore(traces):
    ignores = ['%s/' % trace for trace in traces]
    with open('.gitignore', 'w') as out_file:
        out_file.write('\n'.join(sorted(ignores)))
    return True


def read_json(json_file):
    with open(json_file) as map_file:
        return json.loads(map_file.read(), object_pairs_hook=reject_duplicate_keys)


def update_deps(trace_pairs):
    # Generate substitution string
    replacement = ""
    for (trace, version) in trace_pairs:
        if 'x' in version:
            version = version.strip('x')
            trace_prefix = EXPERIMENTAL_CIPD_PREFIX % getpass.getuser()
        else:
            trace_prefix = CIPD_TRACE_PREFIX
        sub = {'trace': trace, 'version': version, 'trace_prefix': trace_prefix}
        replacement += DEPS_TEMPLATE.format(**sub)

    # Update DEPS to download CIPD dependencies
    new_deps = ""
    with open(DEPS_PATH) as f:
        in_deps = False
        for line in f:
            if in_deps:
                if DEPS_END in line:
                    new_deps += replacement
                    new_deps += line
                    in_deps = False
            else:
                if DEPS_START in line:
                    new_deps += line
                    in_deps = True
                else:
                    new_deps += line
        f.close()

    with open(DEPS_PATH, 'w') as f:
        f.write(new_deps)
        f.close()

    return True


def main():
    json_file = 'restricted_traces.json'
    gni_file = 'restricted_traces_autogen.gni'
    header_file = 'restricted_traces_autogen.h'
    source_file = 'restricted_traces_autogen.cpp'

    json_data = read_json(json_file)
    if 'traces' not in json_data:
        print('Trace data missing traces key.')
        return 1
    trace_pairs = [trace.split(' ') for trace in json_data['traces']]
    traces = [trace_pair[0] for trace_pair in trace_pairs]

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = [json_file]

        # Note: we do not include DEPS in the list of outputs to simplify the integration.
        # Otherwise we'd continually need to regenerate on any roll.
        outputs = [gni_file, header_file, source_file, '.gitignore']

        if sys.argv[1] == 'inputs':
            print(','.join(inputs))
        elif sys.argv[1] == 'outputs':
            print(','.join(outputs))
        else:
            print('Invalid script parameters.')
            return 1
        return 0

    format_args = {
        'script_name': os.path.basename(__file__),
        'data_source_name': json_file,
    }

    if not gen_gni(traces, gni_file, format_args):
        print('.gni file generation failed.')
        return 1

    includes = ['#include "%s"' % get_header_name(trace) for trace in traces]
    trace_infos = ['{"%s", {%s}}' % (trace, get_trace_info(trace)) for trace in traces]

    format_args['filename'] = 'restricted_traces_autogen'
    format_args['num_traces'] = len(trace_infos)
    format_args['trace_includes'] = '\n'.join(includes)
    format_args['trace_infos'] = ',\n'.join(trace_infos)
    if not gen_header(header_file, format_args):
        print('.h file generation failed.')
        return 1

    if not gen_source(source_file, format_args):
        print('.cpp file generation failed.')
        return 1

    if not gen_git_ignore(traces):
        print('.gitignore file generation failed')
        return 1

    if not update_deps(trace_pairs):
        print('DEPS file update failed')
        return 1

    return 0


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