#!/usr/bin/env python3

# Copyright 2017 The Glslang Authors. All rights reserved.
# Copyright (c) 2018-2023 Valve Corporation
# Copyright (c) 2018-2023 LunarG, Inc.
# Copyright (c) 2023-2023 RasterGrid Kft.
#
# 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.

# This script was heavily leveraged from KhronosGroup/glslang
# update_glslang_sources.py.
"""update_deps.py

Get and build dependent repositories using known-good commits.

Purpose
-------

This program is intended to assist a developer of this repository
(the "home" repository) by gathering and building the repositories that
this home repository depend on.  It also checks out each dependent
repository at a "known-good" commit in order to provide stability in
the dependent repositories.

Known-Good JSON Database
------------------------

This program expects to find a file named "known-good.json" in the
same directory as the program file.  This JSON file is tailored for
the needs of the home repository by including its dependent repositories.

Program Options
---------------

See the help text (update_deps.py --help) for a complete list of options.

Program Operation
-----------------

The program uses the user's current directory at the time of program
invocation as the location for fetching and building the dependent
repositories.  The user can override this by using the "--dir" option.

For example, a directory named "build" in the repository's root directory
is a good place to put the dependent repositories because that directory
is not tracked by Git. (See the .gitignore file.)  The "external" directory
may also be a suitable location.
A user can issue:

$ cd My-Repo
$ mkdir build
$ cd build
$ ../scripts/update_deps.py

or, to do the same thing, but using the --dir option:

$ cd My-Repo
$ mkdir build
$ scripts/update_deps.py --dir=build

With these commands, the "build" directory is considered the "top"
directory where the program clones the dependent repositories.  The
JSON file configures the build and install working directories to be
within this "top" directory.

Note that the "dir" option can also specify an absolute path:

$ cd My-Repo
$ scripts/update_deps.py --dir=/tmp/deps

The "top" dir is then /tmp/deps (Linux filesystem example) and is
where this program will clone and build the dependent repositories.

Helper CMake Config File
------------------------

When the program finishes building the dependencies, it writes a file
named "helper.cmake" to the "top" directory that contains CMake commands
for setting CMake variables for locating the dependent repositories.
This helper file can be used to set up the CMake build files for this
"home" repository.

A complete sequence might look like:

$ git clone git@github.com:My-Group/My-Repo.git
$ cd My-Repo
$ mkdir build
$ cd build
$ ../scripts/update_deps.py
$ cmake -C helper.cmake ..
$ cmake --build .

JSON File Schema
----------------

There's no formal schema for the "known-good" JSON file, but here is
a description of its elements.  All elements are required except those
marked as optional.  Please see the "known_good.json" file for
examples of all of these elements.

- name

The name of the dependent repository.  This field can be referenced
by the "deps.repo_name" structure to record a dependency.

- api

The name of the API the dependency is specific to (e.g. "vulkan").

- url

Specifies the URL of the repository.
Example: https://github.com/KhronosGroup/Vulkan-Loader.git

- sub_dir

The directory where the program clones the repository, relative to
the "top" directory.

- build_dir

The directory used to build the repository, relative to the "top"
directory.

- install_dir

The directory used to store the installed build artifacts, relative
to the "top" directory.

- commit

The commit used to checkout the repository.  This can be a SHA-1
object name or a refname used with the remote name "origin".

- deps (optional)

An array of pairs consisting of a CMake variable name and a
repository name to specify a dependent repo and a "link" to
that repo's install artifacts.  For example:

"deps" : [
    {
        "var_name" : "VULKAN_HEADERS_INSTALL_DIR",
        "repo_name" : "Vulkan-Headers"
    }
]

which represents that this repository depends on the Vulkan-Headers
repository and uses the VULKAN_HEADERS_INSTALL_DIR CMake variable to
specify the location where it expects to find the Vulkan-Headers install
directory.
Note that the "repo_name" element must match the "name" element of some
other repository in the JSON file.

- prebuild (optional)
- prebuild_linux (optional)  (For Linux and MacOS)
- prebuild_windows (optional)

A list of commands to execute before building a dependent repository.
This is useful for repositories that require the execution of some
sort of "update" script or need to clone an auxillary repository like
googletest.

The commands listed in "prebuild" are executed first, and then the
commands for the specific platform are executed.

- custom_build (optional)

A list of commands to execute as a custom build instead of using
the built in CMake way of building. Requires "build_step" to be
set to "custom"

You can insert the following keywords into the commands listed in
"custom_build" if they require runtime information (like whether the
build config is "Debug" or "Release").

Keywords:
{0} reference to a dictionary of repos and their attributes
{1} reference to the command line arguments set before start
{2} reference to the CONFIG_MAP value of config.

Example:
{2} returns the CONFIG_MAP value of config e.g. debug -> Debug
{1}.config returns the config variable set when you ran update_dep.py
{0}[Vulkan-Headers][repo_root] returns the repo_root variable from
                                   the Vulkan-Headers GoodRepo object.

- cmake_options (optional)

A list of options to pass to CMake during the generation phase.

- ci_only (optional)

A list of environment variables where one must be set to "true"
(case-insensitive) in order for this repo to be fetched and built.
This list can be used to specify repos that should be built only in CI.

- build_step (optional)

Specifies if the dependent repository should be built or not. This can
have a value of 'build', 'custom',  or 'skip'. The dependent repositories are
built by default.

- build_platforms (optional)

A list of platforms the repository will be built on.
Legal options include:
"windows"
"linux"
"darwin"
"android"

Builds on all platforms by default.

Note
----

The "sub_dir", "build_dir", and "install_dir" elements are all relative
to the effective "top" directory.  Specifying absolute paths is not
supported.  However, the "top" directory specified with the "--dir"
option can be a relative or absolute path.

"""

import argparse
import json
import os
import os.path
import subprocess
import sys
import platform
import multiprocessing
import shlex
import shutil
import stat
import time

KNOWN_GOOD_FILE_NAME = 'known_good.json'

CONFIG_MAP = {
    'debug': 'Debug',
    'release': 'Release',
    'relwithdebinfo': 'RelWithDebInfo',
    'minsizerel': 'MinSizeRel'
}

# NOTE: CMake also uses the VERBOSE environment variable. This is intentional.
VERBOSE = os.getenv("VERBOSE")

DEVNULL = open(os.devnull, 'wb')


def on_rm_error( func, path, exc_info):
    """Error handler for recursively removing a directory. The
    shutil.rmtree function can fail on Windows due to read-only files.
    This handler will change the permissions for the file and continue.
    """
    os.chmod( path, stat.S_IWRITE )
    os.unlink( path )

def make_or_exist_dirs(path):
    "Wrapper for os.makedirs that tolerates the directory already existing"
    # Could use os.makedirs(path, exist_ok=True) if we drop python2
    if not os.path.isdir(path):
        os.makedirs(path)

def command_output(cmd, directory):
    # Runs a command in a directory and returns its standard output stream.
    # Captures the standard error stream and prints it an error occurs.
    # Raises a RuntimeError if the command fails to launch or otherwise fails.
    if VERBOSE:
        print('In {d}: {cmd}'.format(d=directory, cmd=cmd))

    result = subprocess.run(cmd, cwd=directory, capture_output=True, text=True)

    if result.returncode != 0:
        print(f'{result.stderr}', file=sys.stderr)
        raise RuntimeError(f'Failed to run {cmd} in {directory}')

    if VERBOSE:
        print(result.stdout)
    return result.stdout

def run_cmake_command(cmake_cmd):
    # NOTE: Because CMake is an exectuable that runs executables
    # stdout/stderr are mixed together. So this combines the outputs
    # and prints them properly in case there is a non-zero exit code.
    result = subprocess.run(cmake_cmd, 
        stdout = subprocess.PIPE,
        stderr = subprocess.STDOUT,
        text = True
    )

    if VERBOSE:
        print(result.stdout)
        print(f"CMake command: {cmake_cmd} ", flush=True)

    if result.returncode != 0:
        print(result.stdout, file=sys.stderr)
        sys.exit(result.returncode)

def escape(path):
    return path.replace('\\', '/')

class GoodRepo(object):
    """Represents a repository at a known-good commit."""

    def __init__(self, json, args):
        """Initializes this good repo object.

        Args:
        'json':  A fully populated JSON object describing the repo.
        'args':  Results from ArgumentParser
        """
        self._json = json
        self._args = args
        # Required JSON elements
        self.name = json['name']
        self.url = json['url']
        self.sub_dir = json['sub_dir']
        self.commit = json['commit']
        # Optional JSON elements
        self.build_dir = None
        self.install_dir = None
        if json.get('build_dir'):
            self.build_dir = os.path.normpath(json['build_dir'])
        if json.get('install_dir'):
            self.install_dir = os.path.normpath(json['install_dir'])
        self.deps = json['deps'] if ('deps' in json) else []
        self.prebuild = json['prebuild'] if ('prebuild' in json) else []
        self.prebuild_linux = json['prebuild_linux'] if (
            'prebuild_linux' in json) else []
        self.prebuild_windows = json['prebuild_windows'] if (
            'prebuild_windows' in json) else []
        self.custom_build = json['custom_build'] if ('custom_build' in json) else []
        self.cmake_options = json['cmake_options'] if (
            'cmake_options' in json) else []
        self.ci_only = json['ci_only'] if ('ci_only' in json) else []
        self.build_step = json['build_step'] if ('build_step' in json) else 'build'
        self.build_platforms = json['build_platforms'] if ('build_platforms' in json) else []
        self.optional = set(json.get('optional', []))
        self.api = json['api'] if ('api' in json) else None
        # Absolute paths for a repo's directories
        dir_top = os.path.abspath(args.dir)
        self.repo_dir = os.path.join(dir_top, self.sub_dir)
        if self.build_dir:
            self.build_dir = os.path.join(dir_top, self.build_dir)
        if self.install_dir:
            self.install_dir = os.path.join(dir_top, self.install_dir)

        # By default the target platform is the host platform.
        target_platform = platform.system().lower()
        # However, we need to account for cross-compiling.
        for cmake_var in self._args.cmake_var:
            if "android.toolchain.cmake" in cmake_var:
                target_platform = 'android'

        self.on_build_platform = False
        if self.build_platforms == [] or target_platform in self.build_platforms:
            self.on_build_platform = True

    def Clone(self, retries=10, retry_seconds=60):
        if VERBOSE:
            print('Cloning {n} into {d}'.format(n=self.name, d=self.repo_dir))
        for retry in range(retries):
            make_or_exist_dirs(self.repo_dir)
            try:
                command_output(['git', 'clone', self.url, '.'], self.repo_dir)
                # If we get here, we didn't raise an error
                return
            except RuntimeError as e:
                print("Error cloning on iteration {}/{}: {}".format(retry + 1, retries, e))
                if retry + 1 < retries:
                    if retry_seconds > 0:
                        print("Waiting {} seconds before trying again".format(retry_seconds))
                        time.sleep(retry_seconds)
                    if os.path.isdir(self.repo_dir):
                        print("Removing old tree {}".format(self.repo_dir))
                        shutil.rmtree(self.repo_dir, onerror=on_rm_error)
                    continue

                # If we get here, we've exhausted our retries.
                print("Failed to clone {} on all retries.".format(self.url))
                raise e

    def Fetch(self, retries=10, retry_seconds=60):
        for retry in range(retries):
            try:
                command_output(['git', 'fetch', 'origin'], self.repo_dir)
                # if we get here, we didn't raise an error, and we're done
                return
            except RuntimeError as e:
                print("Error fetching on iteration {}/{}: {}".format(retry + 1, retries, e))
                if retry + 1 < retries:
                    if retry_seconds > 0:
                        print("Waiting {} seconds before trying again".format(retry_seconds))
                        time.sleep(retry_seconds)
                    continue

                # If we get here, we've exhausted our retries.
                print("Failed to fetch {} on all retries.".format(self.url))
                raise e

    def Checkout(self):
        if VERBOSE:
            print('Checking out {n} in {d}'.format(n=self.name, d=self.repo_dir))

        if self._args.do_clean_repo:
            if os.path.isdir(self.repo_dir):
                shutil.rmtree(self.repo_dir, onerror = on_rm_error)
        if not os.path.exists(os.path.join(self.repo_dir, '.git')):
            self.Clone()
        self.Fetch()
        if len(self._args.ref):
            command_output(['git', 'checkout', self._args.ref], self.repo_dir)
        else:
            command_output(['git', 'checkout', self.commit], self.repo_dir)

        if VERBOSE:
            print(command_output(['git', 'status'], self.repo_dir))

    def CustomPreProcess(self, cmd_str, repo_dict):
        return cmd_str.format(repo_dict, self._args, CONFIG_MAP[self._args.config])

    def PreBuild(self):
        """Execute any prebuild steps from the repo root"""
        for p in self.prebuild:
            command_output(shlex.split(p), self.repo_dir)
        if platform.system() == 'Linux' or platform.system() == 'Darwin':
            for p in self.prebuild_linux:
                command_output(shlex.split(p), self.repo_dir)
        if platform.system() == 'Windows':
            for p in self.prebuild_windows:
                command_output(shlex.split(p), self.repo_dir)

    def CustomBuild(self, repo_dict):
        """Execute any custom_build steps from the repo root"""
        for p in self.custom_build:
            cmd = self.CustomPreProcess(p, repo_dict)
            command_output(shlex.split(cmd), self.repo_dir)

    def CMakeConfig(self, repos):
        """Build CMake command for the configuration phase and execute it"""
        if self._args.do_clean_build:
            if os.path.isdir(self.build_dir):
                shutil.rmtree(self.build_dir, onerror=on_rm_error)
        if self._args.do_clean_install:
            if os.path.isdir(self.install_dir):
                shutil.rmtree(self.install_dir, onerror=on_rm_error)

        # Create and change to build directory
        make_or_exist_dirs(self.build_dir)
        os.chdir(self.build_dir)

        cmake_cmd = [
            'cmake', self.repo_dir,
            '-DCMAKE_INSTALL_PREFIX=' + self.install_dir
        ]

        # Allow users to pass in arbitrary cache variables
        for cmake_var in self._args.cmake_var:
            pieces = cmake_var.split('=', 1)
            cmake_cmd.append('-D{}={}'.format(pieces[0], pieces[1]))

        # For each repo this repo depends on, generate a CMake variable
        # definitions for "...INSTALL_DIR" that points to that dependent
        # repo's install dir.
        for d in self.deps:
            dep_commit = [r for r in repos if r.name == d['repo_name']]
            if len(dep_commit) and dep_commit[0].on_build_platform:
                cmake_cmd.append('-D{var_name}={install_dir}'.format(
                    var_name=d['var_name'],
                    install_dir=dep_commit[0].install_dir))

        # Add any CMake options
        for option in self.cmake_options:
            cmake_cmd.append(escape(option.format(**self.__dict__)))

        # Set build config for single-configuration generators (this is a no-op on multi-config generators)
        cmake_cmd.append(f'-D CMAKE_BUILD_TYPE={CONFIG_MAP[self._args.config]}')

        # Use the CMake -A option to select the platform architecture
        # without needing a Visual Studio generator.
        if platform.system() == 'Windows' and self._args.generator != "Ninja":
            if self._args.arch.lower() == '64' or self._args.arch == 'x64' or self._args.arch == 'win64':
                cmake_cmd.append('-A')
                cmake_cmd.append('x64')
            else:
                cmake_cmd.append('-A')
                cmake_cmd.append('Win32')

        # Apply a generator, if one is specified.  This can be used to supply
        # a specific generator for the dependent repositories to match
        # that of the main repository.
        if self._args.generator is not None:
            cmake_cmd.extend(['-G', self._args.generator])

        # Removes warnings related to unused CLI
        # EX: Setting CMAKE_CXX_COMPILER for a C project
        if not VERBOSE:
            cmake_cmd.append("--no-warn-unused-cli")

        run_cmake_command(cmake_cmd)

    def CMakeBuild(self):
        """Build CMake command for the build phase and execute it"""
        cmake_cmd = ['cmake', '--build', self.build_dir, '--target', 'install', '--config', CONFIG_MAP[self._args.config]]
        if self._args.do_clean:
            cmake_cmd.append('--clean-first')

        # Xcode / Ninja are parallel by default.
        if self._args.generator != "Ninja" or self._args.generator != "Xcode":
            cmake_cmd.append('--parallel')
            cmake_cmd.append(format(multiprocessing.cpu_count()))

        run_cmake_command(cmake_cmd)

    def Build(self, repos, repo_dict):
        """Build the dependent repo and time how long it took"""
        if VERBOSE:
            print('Building {n} in {d}'.format(n=self.name, d=self.repo_dir))
            print('Build dir = {b}'.format(b=self.build_dir))
            print('Install dir = {i}\n'.format(i=self.install_dir))

        start = time.time()

        # Run any prebuild commands
        self.PreBuild()

        if self.build_step == 'custom':
            self.CustomBuild(repo_dict)
            return

        # Build and execute CMake command for creating build files
        self.CMakeConfig(repos)

        # Build and execute CMake command for the build
        self.CMakeBuild()

        total_time = time.time() - start

        print(f"Installed {self.name} ({self.commit}) in {total_time} seconds", flush=True)

    def IsOptional(self, opts):
        return len(self.optional.intersection(opts)) > 0

def GetGoodRepos(args):
    """Returns the latest list of GoodRepo objects.

    The known-good file is expected to be in the same
    directory as this script unless overridden by the 'known_good_dir'
    parameter.
    """
    if args.known_good_dir:
        known_good_file = os.path.join( os.path.abspath(args.known_good_dir),
            KNOWN_GOOD_FILE_NAME)
    else:
        known_good_file = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), KNOWN_GOOD_FILE_NAME)
    with open(known_good_file) as known_good:
        return [
            GoodRepo(repo, args)
            for repo in json.loads(known_good.read())['repos']
        ]


def GetInstallNames(args):
    """Returns the install names list.

    The known-good file is expected to be in the same
    directory as this script unless overridden by the 'known_good_dir'
    parameter.
    """
    if args.known_good_dir:
        known_good_file = os.path.join(os.path.abspath(args.known_good_dir),
            KNOWN_GOOD_FILE_NAME)
    else:
        known_good_file = os.path.join(
            os.path.dirname(os.path.abspath(__file__)), KNOWN_GOOD_FILE_NAME)
    with open(known_good_file) as known_good:
        install_info = json.loads(known_good.read())
        if install_info.get('install_names'):
            return install_info['install_names']
        else:
            return None


def CreateHelper(args, repos, filename):
    """Create a CMake config helper file.

    The helper file is intended to be used with 'cmake -C <file>'
    to build this home repo using the dependencies built by this script.

    The install_names dictionary represents the CMake variables used by the
    home repo to locate the install dirs of the dependent repos.
    This information is baked into the CMake files of the home repo and so
    this dictionary is kept with the repo via the json file.
    """
    install_names = GetInstallNames(args)
    with open(filename, 'w') as helper_file:
        for repo in repos:
            # If the repo has an API tag and that does not match
            # the target API then skip it
            if repo.api is not None and repo.api != args.api:
                continue
            if install_names and repo.name in install_names and repo.on_build_platform:
                helper_file.write('set({var} "{dir}" CACHE STRING "" FORCE)\n'
                                  .format(
                                      var=install_names[repo.name],
                                      dir=escape(repo.install_dir)))


def main():
    parser = argparse.ArgumentParser(
        description='Get and build dependent repos at known-good commits')
    parser.add_argument(
        '--known_good_dir',
        dest='known_good_dir',
        help="Specify directory for known_good.json file.")
    parser.add_argument(
        '--dir',
        dest='dir',
        default='.',
        help="Set target directory for repository roots. Default is \'.\'.")
    parser.add_argument(
        '--ref',
        dest='ref',
        default='',
        help="Override 'commit' with git reference. E.g., 'origin/main'")
    parser.add_argument(
        '--no-build',
        dest='do_build',
        action='store_false',
        help=
        "Clone/update repositories and generate build files without performing compilation",
        default=True)
    parser.add_argument(
        '--clean',
        dest='do_clean',
        action='store_true',
        help="Clean files generated by compiler and linker before building",
        default=False)
    parser.add_argument(
        '--clean-repo',
        dest='do_clean_repo',
        action='store_true',
        help="Delete repository directory before building",
        default=False)
    parser.add_argument(
        '--clean-build',
        dest='do_clean_build',
        action='store_true',
        help="Delete build directory before building",
        default=False)
    parser.add_argument(
        '--clean-install',
        dest='do_clean_install',
        action='store_true',
        help="Delete install directory before building",
        default=False)
    parser.add_argument(
        '--skip-existing-install',
        dest='skip_existing_install',
        action='store_true',
        help="Skip build if install directory exists",
        default=False)
    parser.add_argument(
        '--arch',
        dest='arch',
        choices=['32', '64', 'x86', 'x64', 'win32', 'win64'],
        type=str.lower,
        help="Set build files architecture (Visual Studio Generator Only)",
        default='64')
    parser.add_argument(
        '--config',
        dest='config',
        choices=['debug', 'release', 'relwithdebinfo', 'minsizerel'],
        type=str.lower,
        help="Set build files configuration",
        default='debug')
    parser.add_argument(
        '--api',
        dest='api',
        default='vulkan',
        choices=['vulkan'],
        help="Target API")
    parser.add_argument(
        '--generator',
        dest='generator',
        help="Set the CMake generator",
        default=None)
    parser.add_argument(
        '--optional',
        dest='optional',
        type=lambda a: set(a.lower().split(',')),
        help="Comma-separated list of 'optional' resources that may be skipped. Only 'tests' is currently supported as 'optional'",
        default=set())
    parser.add_argument(
        '--cmake_var',
        dest='cmake_var',
        action='append',
        metavar='VAR[=VALUE]',
        help="Add CMake command line option -D'VAR'='VALUE' to the CMake generation command line; may be used multiple times",
        default=[])

    args = parser.parse_args()
    save_cwd = os.getcwd()

    # Create working "top" directory if needed
    make_or_exist_dirs(args.dir)
    abs_top_dir = os.path.abspath(args.dir)

    repos = GetGoodRepos(args)
    repo_dict = {}

    print('Starting builds in {d}'.format(d=abs_top_dir))
    for repo in repos:
        # If the repo has an API tag and that does not match
        # the target API then skip it
        if repo.api is not None and repo.api != args.api:
            continue

        # If the repo has a platform whitelist, skip the repo
        # unless we are building on a whitelisted platform.
        if not repo.on_build_platform:
            continue

        # Skip building the repo if its install directory already exists
        # and requested via an option.  This is useful for cases where the
        # install directory is restored from a cache that is known to be up
        # to date.
        if args.skip_existing_install and os.path.isdir(repo.install_dir):
            print('Skipping build for repo {n} due to existing install directory'.format(n=repo.name))
            continue

        # Skip test-only repos if the --tests option was not passed in
        if repo.IsOptional(args.optional):
            continue

        field_list = ('url',
                      'sub_dir',
                      'commit',
                      'build_dir',
                      'install_dir',
                      'deps',
                      'prebuild',
                      'prebuild_linux',
                      'prebuild_windows',
                      'custom_build',
                      'cmake_options',
                      'ci_only',
                      'build_step',
                      'build_platforms',
                      'repo_dir',
                      'on_build_platform')
        repo_dict[repo.name] = {field: getattr(repo, field) for field in field_list}

        # If the repo has a CI whitelist, skip the repo unless
        # one of the CI's environment variable is set to true.
        if len(repo.ci_only):
            do_build = False
            for env in repo.ci_only:
                if env not in os.environ:
                    continue
                if os.environ[env].lower() == 'true':
                    do_build = True
                    break
            if not do_build:
                continue

        # Clone/update the repository
        repo.Checkout()

        # Build the repository
        if args.do_build and repo.build_step != 'skip':
            repo.Build(repos, repo_dict)

    # Need to restore original cwd in order for CreateHelper to find json file
    os.chdir(save_cwd)
    CreateHelper(args, repos, os.path.join(abs_top_dir, 'helper.cmake'))

    sys.exit(0)


if __name__ == '__main__':
    main()