#!/usr/bin/env python3
# Copyright (c) 2019 The Khronos Group Inc.
# Copyright (c) 2019 Valve Corporation
# Copyright (c) 2019 LunarG, Inc.
# Copyright (c) 2019 Google Inc.
#
# 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.
#
# Author: Mike Schuchardt <mikes@lunarg.com>

import argparse
import filecmp
import os
import shutil
import subprocess
import sys
import tempfile

import common_codegen

# files to exclude from --verify check
verify_exclude = ['.clang-format']

def main(argv):
    parser = argparse.ArgumentParser(description='Generate source code for this repository')
    parser.add_argument('registry', metavar='REGISTRY_PATH', help='path to the Vulkan-Headers registry directory')
    group = parser.add_mutually_exclusive_group()
    group.add_argument('-i', '--incremental', action='store_true', help='only update repo files that change')
    group.add_argument('-v', '--verify', action='store_true', help='verify repo files match generator output')
    args = parser.parse_args(argv)

    gen_cmds = [*[[common_codegen.repo_relative('scripts/lvl_genvk.py'),
                   '-registry', os.path.abspath(os.path.join(args.registry,  'vk.xml')),
                   '-quiet',
                   filename] for filename in ["chassis.cpp",
                                              "chassis.h",
                                              "layer_chassis_dispatch.cpp",
                                              "layer_chassis_dispatch.h",
                                              "object_tracker.cpp",
                                              "object_tracker.h",
                                              "parameter_validation.cpp",
                                              "parameter_validation.h",
                                              "thread_safety.cpp",
                                              "thread_safety.h",
                                              "vk_dispatch_table_helper.h",
                                              "vk_enum_string_helper.h",
                                              "vk_extension_helper.h",
                                              "vk_layer_dispatch_table.h",
                                              "vk_object_types.h",
                                              "vk_safe_struct.cpp",
                                              "vk_safe_struct.h",
                                              "lvt_function_pointers.cpp",
                                              "lvt_function_pointers.h",
                                              "vk_typemap_helper.h",
                                              "command_counter_helper.cpp",
                                              "command_counter_helper.h"]],
                [common_codegen.repo_relative('scripts/vk_validation_stats.py'),
                 os.path.abspath(os.path.join(args.registry, 'validusage.json')),
                 '-export_header'],
                [common_codegen.repo_relative('scripts/external_revision_generator.py'),
                 '--json_file', common_codegen.repo_relative('scripts/known_good.json'),
                 '--json_keys', 'repos,0,commit',
                 '-s', 'SPIRV_TOOLS_COMMIT_ID',
                 '-o', 'spirv_tools_commit_id.h']]

    repo_dir = common_codegen.repo_relative('layers/generated')

    # get directory where generators will run
    if args.verify or args.incremental:
        # generate in temp directory so we can compare or copy later
        temp_obj = tempfile.TemporaryDirectory(prefix='VulkanVL_generated_source_')
        temp_dir = temp_obj.name
        gen_dir = temp_dir
    else:
        # generate directly in the repo
        gen_dir = repo_dir

    # run each code generator
    for cmd in gen_cmds:
        print(' '.join(cmd))
        try:
            subprocess.check_call([sys.executable] + cmd, cwd=gen_dir)
        except Exception as e:
            print('ERROR:', str(e))
            return 1

    # optional post-generation steps
    if args.verify:
        # compare contents of temp dir and repo
        temp_files = set(os.listdir(temp_dir))
        repo_files = set(os.listdir(repo_dir))
        files_match = True
        for filename in sorted((temp_files | repo_files) - set(verify_exclude)):
            if filename not in repo_files:
                print('ERROR: Missing repo file', filename)
                files_match = False
            elif filename not in temp_files:
                print('ERROR: Missing generator for', filename)
                files_match = False
            elif not filecmp.cmp(os.path.join(temp_dir, filename),
                               os.path.join(repo_dir, filename),
                               shallow=False):
                print('ERROR: Repo files do not match generator output for', filename)
                files_match = False

        # return code for test scripts
        if files_match:
            print('SUCCESS: Repo files match generator output')
            return 0
        return 1

    elif args.incremental:
        # copy missing or differing files from temp directory to repo
        for filename in os.listdir(temp_dir):
            temp_filename = os.path.join(temp_dir, filename)
            repo_filename = os.path.join(repo_dir, filename)
            if not os.path.exists(repo_filename) or \
               not filecmp.cmp(temp_filename, repo_filename, shallow=False):
                print('update', repo_filename)
                shutil.copyfile(temp_filename, repo_filename)

    return 0

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

