#!/usr/bin/env python3

# This is a variant of the `workspace_status.py` script that in addition to
# plain `git describe` implements a few heuristics to arrive at more to the
# point stamps for directories. But due to the implemented heuristics, it will
# typically take longer to run (especially if you use lots of plugins that
# come without tags) and might slow down your development cycle when used
# as default.
#
# To use it, simply add
#
#   --workspace_status_command="python3 ./tools/workspace_status_release.py"
#
# to your bazel command. So for example instead of
#
#   bazel build release.war
#
# use
#
#   bazel build --workspace_status_command="python3 ./tools/workspace_status_release.py" release.war
#
# Alternatively, you can add
#
#   build --workspace_status_command="python3 ./tools/workspace_status_release.py"
#
# to `.bazelrc` in your home directory.
#
# If the script exits with non-zero code, it's considered as a failure
# and the output will be discarded.

from __future__ import print_function
import os
import subprocess
import sys
import re

ROOT = os.path.abspath(__file__)
while not os.path.exists(os.path.join(ROOT, 'WORKSPACE')):
    ROOT = os.path.dirname(ROOT)
REVISION_CMD = ['git', 'describe', '--always', '--dirty']


def run(command):
    try:
        return subprocess.check_output(command).strip().decode("utf-8")
    except OSError as err:
        print('could not invoke %s: %s' % (command[0], err), file=sys.stderr)
        sys.exit(1)
    except subprocess.CalledProcessError:
        # ignore "not a git repository error" to report unknown version
        return None


def revision_with_match(pattern=None, prefix=False, all_refs=False,
                        return_unmatched=False):
    """Return a description of the current commit

    Keyword arguments:
    pattern    -- (Default: None) Use only refs that match this pattern.
    prefix     -- (Default: False) If True, the pattern is considered a prefix
                  and does not require an exact match.
    all_refs   -- (Default: False) If True, consider all refs, not just tags.
    return_unmatched -- (Default: False) If False and a pattern is given that
                  cannot be matched, return the empty string. If True, return
                  the unmatched description nonetheless.
    """

    command = REVISION_CMD[:]
    if pattern:
        command += ['--match', pattern + ('*' if prefix else '')]
    if all_refs:
        command += ['--all', '--long']

    description = run(command)

    if pattern and not return_unmatched and not description.startswith(pattern):
        return ''
    return description


def branch_with_match(pattern):
    for ref_kind in ['origin/', 'gerrit/', '']:
        description = revision_with_match(ref_kind + pattern, all_refs=True,
                                          return_unmatched=True)
        for cutoff in ['heads/', 'remotes/', ref_kind]:
            if description.startswith(cutoff):
                description = description[len(cutoff):]
        if description.startswith(pattern):
            return description
    return ''


def revision(template=None):
    if template:
        # We use the version `v2.16.19-1-gec686a6352` as running example for the
        # below comments. First, we split into ['v2', '16', '19']
        parts = template.split('-')[0].split('.')

        # Although we have releases with version tags containing 4 numbers, we
        # treat only the first three numbers for simplicity. See discussion on
        # Ib1681b2730cf2c443a3cb55fe6e282f6484e18de.

        if len(parts) >= 3:
            # Match for v2.16.19
            version_part = '.'.join(parts[0:3])
            description = revision_with_match(version_part)
            if description:
                return description

        if len(parts) >= 2:
            version_part = '.'.join(parts[0:2])

            # Match for v2.16.*
            description = revision_with_match(version_part + '.', prefix=True)
            if description:
                return description

            # Match for v2.16
            description = revision_with_match(version_part)
            if description.startswith(version_part):
                return description

            if template.startswith('v'):
                # Match for stable-2.16 branches
                branch = 'stable-' + version_part[1:]
                description = branch_with_match(branch)
                if description:
                    return description

    # None of the template based methods worked out, so we're falling back to
    # generic matches.

    # Match for master branch
    description = branch_with_match('master')
    if description:
        return description

    # Match for anything that looks like a version tag
    description = revision_with_match('v[0-9].', return_unmatched=True)
    if description.startswith('v'):
        return description

    # Still no good tag, so we re-try without any matching
    return revision_with_match()


# prints the stamps for the current working directory
def print_stamps_for_cwd(name, template):
    workspace_status_script = os.path.join(
        'tools', 'workspace_status_release.py')
    if os.path.isfile(workspace_status_script):
        # directory has own workspace_status_command, so we use stamps from that
        for line in run(["python3", workspace_status_script]).split('\n'):
            if re.search("^STABLE_[a-zA-Z0-9().:@/_ -]*$", line):
                print(line)
    else:
        # directory lacks own workspace_status_command, so we create a default
        # stamp
        v = revision(template)
        print('STABLE_BUILD_%s_LABEL %s' % (name.upper(),
                                            v if v else 'unknown'))


# os.chdir is different from plain `cd` in shells in that it follows symlinks
# and does not update the PWD environment. So when using os.chdir to change into
# a symlinked directory from gerrit's `plugins` or `modules` directory, we
# cannot recover gerrit's directory. This prevents the plugins'/modules'
# `workspace_status_release.py` scripts to detect the name they were symlinked
# as (E.g.: it-* plugins sometimes get linked in more than once under different
# names) and to detect gerrit's root directory. To work around this problem, we
# mimic the `cd` of ordinary shells. By using this function, symlink information
# is preserved in the `PWD` environment variable (as it is for example also done
# in bash) and plugin/module `workspace_status_release.py` scripts can pick up
# the needed information from there.
def cd(absolute_path):
    os.environ['PWD'] = absolute_path
    os.chdir(absolute_path)


def print_stamps():
    cd(ROOT)
    gerrit_version = revision()
    print("STABLE_BUILD_GERRIT_LABEL %s" % gerrit_version)
    for kind in ['modules', 'plugins']:
        kind_dir = os.path.join(ROOT, kind)
        for d in os.listdir(kind_dir) if os.path.isdir(kind_dir) else []:
            p = os.path.join(kind_dir, d)
            if os.path.isdir(p):
                cd(p)
                name = os.path.basename(p)
                print_stamps_for_cwd(name, gerrit_version)


if __name__ == '__main__':
    print_stamps()
