#!/usr/bin/env python

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

# 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.

Python Compatibility
--------------------

This program can be used with Python 2.7 and Python 3.

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.

- 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".
For example, this field can be set to "origin/sdk-1.1.77" to
select the end of the sdk-1.1.77 branch.

- 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.
Typically, this list might contain "TRAVIS" and/or "APPVEYOR" because
each of these CI systems sets an environment variable with its own
name to "true".  Note that this could also be (ab)used to control
the processing of the repo with any environment variable.  The default
is an empty list, which means that the repo is always processed.

- 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"

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.

"""

from __future__ import print_function

import argparse
import json
import distutils.dir_util
import os.path
import subprocess
import sys
import platform
import multiprocessing
import shlex
import shutil

KNOWN_GOOD_FILE_NAME = 'known_good.json'

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

VERBOSE = False

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


def command_output(cmd, directory, fail_ok=False):
    """Runs a command in a directory and returns its standard output stream.

    Captures the standard error stream and prints it if error.

    Raises a RuntimeError if the command fails to launch or otherwise fails.
    """
    if VERBOSE:
        print('In {d}: {cmd}'.format(d=directory, cmd=cmd))
    p = subprocess.Popen(
        cmd, cwd=directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (stdout, stderr) = p.communicate()
    if p.returncode != 0:
        print('*** Error ***\nstderr contents:\n{}'.format(stderr))
        if not fail_ok:
            raise RuntimeError('Failed to run {} in {}'.format(cmd, directory))
    if VERBOSE:
        print(stdout)
    return stdout

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 = json['build_dir']
        if json.get('install_dir'):
            self.install_dir = 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 []
        # 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)
	    # Check if platform is one to build on
        self.on_build_platform = False
        if self.build_platforms == [] or platform.system().lower() in self.build_platforms:
            self.on_build_platform = True

    def Clone(self):
        distutils.dir_util.mkpath(self.repo_dir)
        command_output(['git', 'clone', self.url, '.'], self.repo_dir)

    def Fetch(self):
        command_output(['git', 'fetch', 'origin'], self.repo_dir)

    def Checkout(self):
        print('Checking out {n} in {d}'.format(n=self.name, d=self.repo_dir))
        if self._args.do_clean_repo:
            shutil.rmtree(self.repo_dir)
        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)
        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:
            shutil.rmtree(self.build_dir)
        if self._args.do_clean_install:
            shutil.rmtree(self.install_dir)

        # Create and change to build directory
        distutils.dir_util.mkpath(self.build_dir)
        os.chdir(self.build_dir)

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

        # 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):
                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(option)

        # Set build config for single-configuration generators
        if platform.system() == 'Linux' or platform.system() == 'Darwin':
            cmake_cmd.append('-DCMAKE_BUILD_TYPE={config}'.format(
                config=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':
            if self._args.arch == '64' or self._args.arch == 'x64' or self._args.arch == 'win64':
                cmake_cmd.append('-A')
                cmake_cmd.append('x64')

        if VERBOSE:
            print("CMake command: " + " ".join(cmake_cmd))

        ret_code = subprocess.call(cmake_cmd)
        if ret_code != 0:
            sys.exit(ret_code)

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

        if platform.system() == 'Windows':
            cmake_cmd.append('--config')
            cmake_cmd.append(CONFIG_MAP[self._args.config])

        # Speed up the build.
        if platform.system() == 'Linux' or platform.system() == 'Darwin':
            cmake_cmd.append('--')
            cmake_cmd.append('-j{ncpu}'
                             .format(ncpu=multiprocessing.cpu_count()))
        if platform.system() == 'Windows':
            cmake_cmd.append('--')
            cmake_cmd.append('/maxcpucount')

        if VERBOSE:
            print("CMake command: " + " ".join(cmake_cmd))

        ret_code = subprocess.call(cmake_cmd)
        if ret_code != 0:
            sys.exit(ret_code)

    def Build(self, repos, repo_dict):
        """Build the dependent repo"""
        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))

        # 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()


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 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=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/master'")
    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(
        '--arch',
        dest='arch',
        choices=['32', '64', 'x86', 'x64', 'win32', 'win64'],
        type=str.lower,
        help="Set build files architecture (Windows)",
        default='64')
    parser.add_argument(
        '--config',
        dest='config',
        choices=['debug', 'release', 'relwithdebinfo', 'minsizerel'],
        type=str.lower,
        help="Set build files configuration",
        default='debug')

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

    # Create working "top" directory if needed
    distutils.dir_util.mkpath(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 a platform whitelist, skip the repo
        # unless we are building on a whitelisted platform.
        if not repo.on_build_platform:
            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 not env 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()
