# Copyright 2023 The Dawn & 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.
"""
Helper script to download Dawn's source dependencies without the need to
install depot_tools by manually. This script implements a subset of
`gclient sync`.

This helps embedders, for example through CMake, get all the sources with
a single add_subdirectory call (or FetchContent) instead of more complex setups

Note that this script executes blindly the content of DEPS file, run it only on
a project that you trust not to contain malicious DEPS files.
"""

import os
import sys
import subprocess
import argparse
from pathlib import Path

parser = argparse.ArgumentParser(
    prog='fetch_dawn_dependencies',
    description=__doc__,
)

parser.add_argument('-d',
                    '--directory',
                    type=str,
                    default="",
                    help="""
    Working directory, in which we read and apply DEPS files recusively. If not
    specified, the current working directory is used.
    """)

parser.add_argument('-g',
                    '--git',
                    type=str,
                    default="git",
                    help="""
    Path to the git command used to. By default, git is retrieved from the PATH.
    You may also use this option to specify extra argument for all calls to git.
    """)

parser.add_argument('-s',
                    '--shallow',
                    action='store_true',
                    default=True,
                    help="""
    Clone repositories without commit history (only getting data for the
    requested commit).
    NB: The git server hosting the dependencies must have turned on the
    `uploadpack.allowReachableSHA1InWant` option.
    NB2: git submodules may not work as expected (but they are not used by Dawn
    dependencies).
    """)
parser.add_argument('-ns',
                    '--no-shallow',
                    action='store_false',
                    dest='shallow',
                    help="Deactivate shallow cloning.")

parser.add_argument('-t',
                    '--use-test-deps',
                    action='store_true',
                    default=False,
                    help="""
    Fetch dependencies needed for testing
    """)


def main(args):
    # The dependencies that we need to pull from the DEPS files.
    # Dependencies of dependencies are prefixed by their ancestors.
    required_submodules = [
        'third_party/vulkan-deps',
        'third_party/vulkan-deps/spirv-headers/src',
        'third_party/vulkan-deps/spirv-tools/src',
        'third_party/vulkan-deps/vulkan-headers/src',
        'third_party/vulkan-deps/vulkan-loader/src',
        'third_party/vulkan-deps/vulkan-tools/src',
        'third_party/glfw',
        'third_party/abseil-cpp',
        'third_party/jinja2',
        'third_party/markupsafe',
    ]

    if args.use_test_deps:
        required_submodules += [
            'third_party/googletest',
        ]

    root_dir = Path(args.directory).resolve()

    process_dir(args, root_dir, required_submodules)


def process_dir(args, dir_path, required_submodules):
    """
    Install dependencies for the provided directory by processing the DEPS file
    that it contains (if it exists).
    Recursively install dependencies in sub-directories that are created by
    cloning dependencies.
    """
    deps_path = dir_path / 'DEPS'
    if not deps_path.is_file():
        return

    log(f"Listing dependencies from {dir_path}")
    DEPS = open(deps_path).read()

    ldict = {}
    exec(DEPS, globals(), ldict)
    deps = ldict.get('deps')
    variables = ldict.get('vars', {})

    if deps is None:
        log(f"ERROR: DEPS file '{deps_path}' does not define a 'deps' variable"
            )
        exit(1)

    for submodule in required_submodules:
        if submodule not in deps:
            continue
        submodule_path = dir_path / Path(submodule)

        raw_url = deps[submodule]['url']
        git_url, git_tag = raw_url.format(**variables).rsplit('@', 1)

        # Run git from within the submodule's path (don't use for clone)
        git = lambda *x: subprocess.run([args.git, '-C', submodule_path, *x],
                                        capture_output=True)

        log(f"Fetching dependency '{submodule}'")
        if not submodule_path.is_dir():
            if args.shallow:
                log(f"Shallow cloning '{git_url}' at '{git_tag}' into '{submodule_path}'"
                    )
                shallow_clone(git, git_url, git_tag, submodule_path)
            else:
                log(f"Cloning '{git_url}' into '{submodule_path}'")
                subprocess.run([
                    args.git,
                    'clone',
                    '--recurse-submodules',
                    git_url,
                    submodule_path,
                ],
                               capture_output=True)

            log(f"Checking out tag '{git_tag}'")
            git('checkout', git_tag)

        elif (submodule_path / ".git").is_dir():
            # The module was already cloned, but we may need to update it
            proc = git('rev-parse', 'HEAD')
            need_update = proc.stdout.decode().strip() != git_tag

            if need_update:
                # The module was already cloned, but we may need to update it
                proc = git('cat-file', '-t', git_tag)
                git_tag_exists = proc.returncode == 0

                if not git_tag_exists:
                    log(f"Updating '{submodule_path}' from '{git_url}'")
                    if args.shallow:
                        git('fetch', 'origin', git_tag, '--depth', '1')
                    else:
                        git('fetch', 'origin')

                log(f"Checking out tag '{git_tag}'")
                git('checkout', git_tag)

        else:
            # The caller may have "flattened" the source tree to get rid of
            # some heavy submodules.
            log(f"(Overridden by a local copy of the submodule)")

        # Recursive call
        required_subsubmodules = [
            m[len(submodule) + 1:] for m in required_submodules
            if m.startswith(submodule + "/")
        ]
        process_dir(args, submodule_path, required_subsubmodules)


def shallow_clone(git, git_url, git_tag, submodule_path):
    """
    Fetching only 1 commit is not exposed in the git clone API, so we decompose
    it manually in git init, git fetch, git reset.
    """
    submodule_path.mkdir()
    git('init')
    git('remote', 'add', 'origin', git_url)
    git('fetch', 'origin', git_tag, '--depth', '1')


def log(msg):
    """Just makes it look good in the CMake log flow."""
    print(f"-- -- {msg}")


class Var:
    """
    Mock Var class, that the content of DEPS files assume to exist when they
    are exec-ed.
    """
    def __init__(self, name):
        self.name = name

    def __add__(self, text):
        return self.name + text

    def __radd__(self, text):
        return text + self.name


if __name__ == "__main__":
    main(parser.parse_args())
