# Copyright 2019 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.
"""Recipe for updating the code search super manifest project."""

from PB.recipes.fuchsia.code_search_superproject import InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"

DEPS = [
    "fuchsia/checkout",
    "fuchsia/git",
    "fuchsia/git_checkout",
    "fuchsia/jiri",
    "fuchsia/status_check",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties

GENERATE_SCRIPT = "setup.sh"

LOCAL_BRANCH_NAME = "latest"


def reset_submodule_state(api, project_path):
    """Reset submodule state if .gitmodules file already exists."""
    if not api.path.exists(project_path.join(".gitmodules")):
        return
    with api.step.nest("reset submodule state"):
        submodule_configs = (
            api.git.config(
                "--name-only",
                "--null",
                "--file",
                ".gitmodules",
                "--get-regexp",
                "submodule.*path",
                step_name="get submodule configs",
                stdout=api.raw_io.output_text(),
                step_test_data=lambda: api.raw_io.test_api.stream_output_text(
                    "\x00".join(
                        [
                            "submodule.a.path",
                            "submodule.b.path",
                        ]
                    )
                ),
            )
            .stdout.rstrip("\x00")
            .split("\x00")
        )
        for submodule_config in submodule_configs:
            submodule_path = api.git.config(
                "--null",
                "--file",
                ".gitmodules",
                "--get",
                submodule_config,
                step_name="get submodule path",
                stdout=api.raw_io.output_text(),
                step_test_data=lambda: api.raw_io.test_api.stream_output_text(
                    "path/to/submodule\x00"
                ),
            ).stdout.rstrip("\x00")
            api.git(
                "rm %s" % submodule_path,
                "rm",
                "--cached",
                "--",
                submodule_path,
                ok_ret="any",
            )
            submodule_section_name = submodule_config[: -len(".path")]
            api.git.config(
                "--file",
                ".gitmodules",
                "--remove-section",
                submodule_section_name,
                step_name="remove section %s" % submodule_section_name,
            )
            api.git.add(add_all=True, force=True)


def RunSteps(api, props):
    fuchsia_checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest,
        remote=props.remote,
        fetch_packages=False,
    )

    superproject_checkout_root, checkout_revision = api.git_checkout(
        props.superproject_remote
    )

    if props.preserve_root:
        with api.context(cwd=superproject_checkout_root):
            api.git.raw_checkout(branch=LOCAL_BRANCH_NAME)

    with api.step.nest("checkout super manifest project"):
        super_manifest_project_path = fuchsia_checkout.root_dir.join("super")
        api.file.ensure_directory("make dirs", super_manifest_project_path)

        _, base_revision = api.git_checkout(
            props.super_manifest_project,
            path=super_manifest_project_path,
            submodules=False,
            ignore_build_input=True,
        )

    with api.context(cwd=super_manifest_project_path):
        reset_submodule_state(api, super_manifest_project_path)
        # For details, see:
        # https://fuchsia.googlesource.com/jiri/+/main/cmd/jiri/generate-gitmodules.go
        generate_script_path = super_manifest_project_path.join(GENERATE_SCRIPT)
        api.jiri.generate_gitmodules(
            ".gitmodules",
            generate_script=generate_script_path,
            redirect_root=not props.preserve_root,
        )

        api.step("run %s" % GENERATE_SCRIPT, [generate_script_path])
        api.file.remove("remove %s" % GENERATE_SCRIPT, generate_script_path)

        api.git.add(add_all=True, force=True)
        # Only commit if we have a diff, otherwise commit fails.
        if api.git.diff(
            ref_base=base_revision, cached=True, exit_code=True, ok_ret="any"
        ).retcode:
            api.git.commit(message="Update submodules to %s" % checkout_revision)

        if props.preserve_root:
            # Add our local sandbox superproject checkout as a new remote of the super
            # manifest project's Git repo, and merge in the history.
            # TODO(yupingz): Resolve merge conflicts.
            source_remote = "local-upstream"
            api.git.remote_add(source_remote, superproject_checkout_root)
            api.git.fetch(source_remote)
            api.git(
                "git merge",
                "merge",
                "-m",
                "merge upstream changes",
                "-X",
                "theirs",
                "--allow-unrelated-histories",
                "%s/%s" % (source_remote, LOCAL_BRANCH_NAME),
            )
        # Only push if we have a diff.
        if api.git.diff(
            step_name="check for push",
            ref_base=base_revision,
            cached=True,
            exit_code=True,
            ok_ret="any",
        ).retcode:
            # Skip pushing entirely instead of setting --dry-run because a dry
            # run push may fail if it races with a production build.
            if not props.dry_run:
                api.git.push(
                    "HEAD:main",
                    options=["nokeycheck", "skip-validation"],
                )


def GenTests(api):
    source_info = [
        {
            "name": "integration",
            "remote": "https://fuchsia.googlesource.com/integration",
            "revision": "a491082dc1b632bbcd60ba3618d20b503c2de738",
            "relativePath": "integration",
        },
    ]

    def props(**kwargs):
        return api.properties(
            remote="https://fuchsia.googlesource.com/integration",
            manifest="flower",
            superproject_remote="https://turquoise-internal.googlesource.com/sandbox/iankaz/public/superproject",
            super_manifest_project="https://fuchsia.googlesource.com/super",
            **kwargs
        )

    yield api.status_check.test("preserve_root") + props(
        preserve_root=True
    ) + api.path.exists(
        api.path["start_dir"].join("fuchsia", "super", ".gitmodules")
    ) + api.checkout.source_info(
        source_info
    )

    yield api.status_check.test("no_diff") + props() + api.checkout.source_info(
        source_info
    ) + api.path.exists(api.path["start_dir"].join("fuchsia", "super", ".gitmodules"))

    yield api.status_check.test("yes_diff") + props() + api.step_data(
        "git diff", retcode=1
    ) + api.path.exists(
        api.path["start_dir"].join("fuchsia", "super", ".gitmodules")
    ) + api.checkout.source_info(
        source_info
    ) + api.step_data(
        "check for push", retcode=1
    )

    yield api.status_check.test("yes_diff_no_modules") + props() + api.step_data(
        "git diff", retcode=1
    ) + api.checkout.source_info(source_info) + api.step_data(
        "check for push", retcode=1
    )
