#!/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)
    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:
            print("Error running " + " ".join(cmd) + ": " + stdout, stderr)
            return 1


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