#!/usr/bin/env python3

# Copyright 2021 The Tint Authors.
#
# 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.

# Collect all .spvasm files under a given directory, assemble them using
# spirv-as, and emit the assembled binaries to a given corpus directory,
# flattening their file names by replacing path separators with underscores.
# If the output directory already exists, it will be deleted and re-created.
# Files ending with ".expected.spvasm" are skipped.
#
# The intended use of this script is to generate a corpus of SPIR-V
# binaries for fuzzing.
#
# Usage:
#    generate_spirv_corpus.py <input_dir> <corpus_dir> <path to spirv-as>

import os
import pathlib
import shutil
import subprocess
import sys


def list_spvasm_files(root_search_dir):
    for root, folders, files in os.walk(root_search_dir):
        for filename in folders + files:
            if pathlib.Path(filename).suffix == ".spvasm":
                yield os.path.join(root, filename)


def main():
    if len(sys.argv) != 4:
        print("Usage: " + sys.argv[0] +
              " <input dir> <output dir> <spirv-as path>")
        return 1
    input_dir: str = os.path.abspath(sys.argv[1].rstrip(os.sep))
    corpus_dir: str = os.path.abspath(sys.argv[2])
    spirv_as_path: str = os.path.abspath(sys.argv[3])
    if os.path.exists(corpus_dir):
        shutil.rmtree(corpus_dir)
    os.makedirs(corpus_dir)

    # It might be that some of the attempts to convert SPIR-V assembly shaders
    # into SPIR-V binaries go wrong. It is sensible to tolerate a small number
    # of such errors, to avoid fuzzer preparation failing due to bugs in
    # spirv-as. But it is important to know when a large number of failures
    # occur, in case something is more deeply wrong.
    num_errors = 0
    max_tolerated_errors = 10
    logged_errors = ""

    for in_file in list_spvasm_files(input_dir):
        if in_file.endswith(".expected.spvasm"):
            continue
        out_file = os.path.splitext(
            corpus_dir + os.sep +
            in_file[len(input_dir) + 1:].replace(os.sep, '_'))[0] + ".spv"
        cmd = [
            spirv_as_path, "--target-env", "spv1.3", in_file, "-o", out_file
        ]
        proc = subprocess.Popen(cmd,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        stdout, stderr = proc.communicate()
        if proc.returncode != 0:
            num_errors += 1
            logged_errors += "Error running " + " ".join(
                cmd) + ": " + stdout.decode('utf-8') + stderr.decode('utf-8')

    if num_errors > max_tolerated_errors:
        print("Too many (" + str(num_errors) +
              ") errors occured while generating the SPIR-V corpus.")
        print(logged_errors)
        return 1


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