#!/usr/bin/env fuchsia-vendored-python

# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import re
import subprocess
import sys
import xml.etree.ElementTree as ET


class Env(object):
    def __init__(self, root_dir):
        self.root_dir = root_dir
        self.integration_dir = os.path.normpath(
            os.path.join(root_dir, "integration")
        )
        self.stem_cache = os.path.normpath(
            os.path.join(root_dir, ".fx-sync-from-stem.cache")
        )


def git(args, cwd):
    return subprocess.check_output(["git"] + args, cwd=cwd).decode()


def jiri(args, cwd):
    return subprocess.check_output(["jiri"] + args, cwd=cwd).decode()


def message(msg):
    print("sync-from-stem:", msg)


def reverse_commits(fuchsia_commits_for_integration):
    """
    Convert a map of "integration_revs -> [fuchsia_revs]" to
    "fuchsia_revs -> integration_revs".
    """
    fuchsia_rev_to_integration = {}
    for integ, fuch_revs in fuchsia_commits_for_integration.items():
        for f in fuch_revs:
            fuchsia_rev_to_integration[f] = integ
    return fuchsia_rev_to_integration


def update_stem_history(env):
    """
    Return a map of "fuchsia_rev -> integration_revs".

    This is a relatively expensive operation, and requires performing a git
    fetch of the integration repo and parsing the "stem" file. We cache results
    in the locations specified by "env" to speed up future calls.
    """
    message("updating in %s" % env.integration_dir)
    git(["fetch", "origin", "-q"], cwd=env.integration_dir)
    git(["fetch", "origin", "-q"], cwd=env.root_dir)
    git(["checkout", "origin/master", "-q"], cwd=env.integration_dir)
    cur_head = git(["rev-parse", "HEAD"], cwd=env.integration_dir).strip()
    message("integration now at %s" % cur_head)

    data = {}
    data["integration_commits"] = []
    data["head"] = ""
    data["integration_fuchsia_pairs"] = []
    data["fuchsia_commits_for_integration"] = {}

    # Caches:
    # - integration commit -> fuchsia/stem commit (ordered by integration
    #   commit)
    #
    # - Then, a cache of the range of fuchsia commits between those, i.e:
    #
    # integ0 -> fuchsia0
    #        -> fuchsia0-1
    #        -> fuchsia0-2
    # integ1 -> fuchsia1
    # integ2 -> fuchsia2
    #        -> fuchsia2-1
    #        -> fuchsia2-2
    #        -> fuchsia2-3
    # integ3 -> fuchsia3
    #
    # - And, a reversed version of above from fuchsia to its integration
    #   hash. The reversed isn't cached, it's just reversed on load.

    if os.path.exists(env.stem_cache):
        data = json.load(open(env.stem_cache, "r"))
        if data["head"] == cur_head:
            # Already up to date.
            return reverse_commits(data["fuchsia_commits_for_integration"])

    if not data["head"]:
        integration_revs_to_update = cur_head
    else:
        integration_revs_to_update = data["head"] + ".." + cur_head

    stem_paths = ["fuchsia/stem", "stem"]
    for p in stem_paths:
        if os.path.exists(os.path.join(env.integration_dir, p)):
            stem_path = p
            break
    else:
        print("Could not find stem manifest", file=sys.stderr)
        sys.exit(1)

    message("getting integration commits from %s" % integration_revs_to_update)
    # Arbitrarily truncated at the start of 2020 because sync'ing back farther
    # than that probably won't build for other reasons, and because the stem
    # file location changed in old revisions, https://fxbug.dev/42131900.
    new_integration_commits = git(
        [
            "log",
            "--format=%H",
            "--since=2020-01-01",
            integration_revs_to_update,
            "--",
            stem_path,
        ],
        cwd=env.integration_dir,
    ).split()
    data["integration_commits"] = (
        new_integration_commits + data["integration_commits"]
    )
    data["head"] = cur_head

    # Now we have an up-to-date list of all integration commits, along
    # with new_integration_commits being the ones that have just been
    # added. Read the manifest for each of the new ones, and then add
    # those to the integration_fuchsia_pairs.

    def get_fuchsia_rev_for_integration_commit(ic):
        manifest_root = ET.fromstring(
            git(["show", ic + ":" + stem_path], cwd=env.integration_dir)
        )
        for project in manifest_root.find("projects"):
            if project.get("name") == "fuchsia":
                return project.get("revision")
        print(
            'Could not find "fuchsia" project in "%s" file at '
            "revision %s." % (stem_path, ic),
            file=sys.stderr,
        )
        sys.exit(1)

    message(
        "caching fuchsia commits for %d integration commits"
        % len(new_integration_commits)
    )
    new_integration_fuchsia_pairs = []
    for i, ic in enumerate(new_integration_commits):
        print("\r%d/%d" % (i, len(new_integration_commits)), end="")
        new_integration_fuchsia_pairs.append(
            (ic, get_fuchsia_rev_for_integration_commit(ic))
        )
    print("\r\033[K", end="")  # Clear line.
    data["integration_fuchsia_pairs"] = (
        new_integration_fuchsia_pairs + data["integration_fuchsia_pairs"]
    )

    message("caching fuchsia commit ranges")
    # integration_fuchsia_pairs is the first important mapping that's
    # useful, but we don't know what's between each of the fuchsia
    # commits. For each of the new integration commits, log from its
    # fuchsia commit to the preceding fuchsia commit.
    # For example, if we have integration commits i0, i1, i2, i3, ...
    # each with corresponding fuchsia commits f0, f1, f2, f3, ... and
    # the new ones that were just added above were i0 and i1, then we
    # need to log f0..f1, f1..f2, and f2..f3.

    # Special case for the nothing-cached-yet case -- we need to from
    # the last new commit to the newest old commit (per above comment),
    # but on the first run, there's nothing before the oldest new
    # commit. We don't really care about syncing that far back anyway,
    # so just drop that last one.
    last_num = min(
        len(new_integration_fuchsia_pairs),
        len(data["integration_fuchsia_pairs"]) - 1,
    )
    for i in range(last_num):
        cur = data["integration_fuchsia_pairs"][i]
        older = data["integration_fuchsia_pairs"][i + 1]
        fuchsia_cur = cur[1]
        fuchsia_older = older[1]
        print("\r%d/%d" % (i, len(new_integration_fuchsia_pairs)), end="")
        fuchsia_revs = git(
            ["log", "--format=%H", fuchsia_older + ".." + fuchsia_cur],
            cwd=env.root_dir,
        ).split()
        data["fuchsia_commits_for_integration"][cur[0]] = fuchsia_revs
    print("\r\033[K", end="")  # Clear line.

    json.dump(data, open(env.stem_cache, "w"))
    return reverse_commits(data["fuchsia_commits_for_integration"])


def set_jiri_ignore(env, to):
    jiri(["project-config", "-ignore=" + to], cwd=env.root_dir)


def save_and_fix_fuchsia_jiri_project_config(env):
    to_return = None
    for line in jiri(["project-config"], cwd=env.root_dir).splitlines()[1:]:
        if line.startswith("ignore:"):
            left, _, right = line.partition(": ")
            to_return = right.strip()
            break
    else:
        print(
            'Could not find current "ignore" value in jiri project-config',
            file=sys.stderr,
        )
        sys.exit(1)
    set_jiri_ignore(env, "true")
    return to_return


def extract_and_output_rebase_warnings(log):
    """Look for specific rebase warning output from jiri. If rebase output
        is found, output a message about each, and return False, otherwise True.

        The integration repo is ignored as it will always be pinned to our
        sync branch.

    # Output and fail if we see the rebase note.
    >>> extract_and_output_rebase_warnings('''blah blah blah
    ... and then some
    ... [10:45:14.203] WARN: For Project "project/somename", branch "muhbranch" does not track any remote branch.
    ... To rebase it update with -rebase-untracked flag, or to rebase it manually run
    ... WE WANT TO RUN THIS LINE
    ... then more stuff down here that
    ... we don't want
    ... ''')
    sync-from-stem: muhbranch in project/somename has no upstream, to rebase:
    sync-from-stem:     WE WANT TO RUN THIS LINE
    False

    # But ignore all the normal goop, and don't fail.
    >>> extract_and_output_rebase_warnings('''[12:09:05.864] Updating all projects
    ... [12:09:14.529] WARN: 1 project(s) is/are marked to be deleted. Run 'jiri update -gc' to delete them.
    ... Or run 'jiri update -v' or 'jiri status -d' to see the list of projects.
    ...
    ... [12:09:14.611] WARN: For Project "integration", branch "lock_at_d3d488db58e068abf60750b94e4e82f8fdc9b57c" does not track any remote branch.
    ... To rebase it update with -rebase-untracked flag, or to rebase it manually run
    ... git -C "../integration" checkout lock_at_d3d488db58e068abf60750b94e4e82f8fdc9b57c && git -C "../integration" rebase e2a923d06860f7a82ad70c429e14328530f41f7e
    ...
    ... PROGRESS: Fetching CIPD packages
    ... ''')
    True
    """
    ret = True
    non_tracking = re.compile(
        r'WARN: For Project "(.*)", branch "(.*)" does not track'
    )
    err = []
    capture_lines = 0
    for line in log.splitlines():
        if capture_lines:
            if capture_lines == 1:
                err.append("    " + line)
            capture_lines -= 1
            continue
        mo = non_tracking.search(line)
        if mo and mo.group(1) != "integration":
            err.append("%s in %s has no upstream, to rebase:" % mo.group(2, 1))
            capture_lines = 2

    for x in err:
        message(x)
    return not err


def to_revision(env, fc, ic):
    prev_ignore = save_and_fix_fuchsia_jiri_project_config(env)
    try:
        message("checking out integration %s..." % ic)
        git(
            ["checkout", "-q", "-B", "lock_at_%s" % ic, ic],
            cwd=env.integration_dir,
        )
        message("updating dependencies with jiri...")
        log = jiri(["update", "-local-manifest=true"], cwd=env.root_dir)
        return extract_and_output_rebase_warnings(log)
    finally:
        set_jiri_ignore(env, prev_ignore)


def find_first_non_local_commit(env):
    return git(
        ["merge-base", "HEAD", "origin/master"], cwd=env.root_dir
    ).strip()


def abort_if_is_dirty(git_repo):
    dirty = git(["status", "--porcelain", "--untracked-files=no"], cwd=git_repo)
    if dirty:
        print(
            "%s has uncommitted changes, aborting" % git_repo, file=sys.stderr
        )
        sys.exit(1)


def main():
    if len(sys.argv) != 2 or not os.path.isdir(sys.argv[1]):
        print(
            """usage: sync-from-stem.py fuchsia_dir

Sync integration and deps to a state matching fuchsia.git state.

1. Finds the first commit on the current branch that's been integrated
   upstream (i.e. not your local commits).
2. Then, finds the integration repo commit that would include that found
   commit.
3. Syncs other dependencies to match that integration commit.

In this way, you can checkout, update, rebase, etc. your fuchsia.git
branches and then use this script (rather than jiri update) to update
the rest of the tree to match that branch. This allows working as if
fuchsia.git is the "root" of the tree, even though that data is really
stored in the integration repo.
""",
            file=sys.stderr,
        )
        return 1
    env = Env(os.path.abspath(sys.argv[1]))
    abort_if_is_dirty(env.integration_dir)
    f_to_i = update_stem_history(env)

    fuchsia_rev = find_first_non_local_commit(env)
    if fuchsia_rev not in f_to_i:
        message(
            "fuchsia rev %s not found in integration, not rolled yet?"
            % fuchsia_rev
        )
        return 1
    if not to_revision(env, fuchsia_rev, f_to_i[fuchsia_rev]):
        return 2
    message(
        "synced integration to %s, which matches fuchsia rev %s"
        % (f_to_i[fuchsia_rev], fuchsia_rev)
    )
    return 0


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