# Copyright 2018 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 building and testing cobalt-registry.

Uses Cobalt's cobaltb.py script to build the config_parser tool, then
runs it on Cobalt's `config` repo.
"""

from future.moves.urllib.parse import urlparse

from PB.recipes.fuchsia.cobalt_config import InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"

DEPS = [
    "fuchsia/build",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/goma",
    "fuchsia/jiri",
    "fuchsia/sso",
    "recipe_engine/buildbucket",
    "recipe_engine/context",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    api.goma.ensure()

    # Check out the project from the specified manifest.
    checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest, remote=props.remote
    )

    with api.context(cwd=checkout.root_dir):
        cobalt_config_projects = api.jiri.project(
            ["cobalt-registry"],
            test_data=[
                {
                    "name": "cobalt-registry",
                    "path": str(checkout.root_dir.join("cobalt-registry")),
                    "remote": "https://fuchsia.googlesource.com/cobalt-registry",
                },
                {
                    "name": "cobalt-registry",
                    "path": str(checkout.root_dir.join("other/cobalt-registry")),
                    "remote": "https://not-fuchsia.googlesource.com/cobalt-registry",
                },
            ],
        ).json.output

    # Filter config repos based on input.
    changes = api.buildbucket.build.input.gerrit_changes
    if changes and changes[0].project == "cobalt-registry":
        cobalt_config_projects = [
            p
            for p in cobalt_config_projects
            if urlparse(api.sso.sso_to_https(p["remote"])).netloc
            == urlparse(changes[0].host).path.replace("-review", "")
        ]

    build_results = api.build.with_options(
        checkout=checkout, fint_params_path=props.fint_params_path
    )

    # Root of the cobalt repo as checked out by the manifest.
    cobalt_src_dir = checkout.root_dir.join("third_party/cobalt")

    for cobalt_config_project in cobalt_config_projects:
        # Root of the config repo as checked out by the manifest.
        config_src_dir = api.path.abs_to_path(cobalt_config_project["path"])

        config_parser_bin = build_results.tool("config_parser")
        # Run config_parser on the config repo checkout.
        api.step(
            "check config",
            [
                config_parser_bin,
                "--output_file",
                checkout.root_dir.join("new_config"),
                "--config_dir",
                config_src_dir,
                "--allow_empty_output",
                "--privacy_encoding_params_file",
                cobalt_src_dir.join(
                    "src/algorithms/privacy/data/privacy_encoding_params"
                ),
            ],
        )

        with api.context(cwd=config_src_dir):
            api.step("checkout parent", ["git", "checkout", "HEAD^"])

        api.step(
            "check parent config",
            [
                config_parser_bin,
                "--output_file",
                checkout.root_dir.join("old_config"),
                "--config_dir",
                config_src_dir,
                "--allow_empty_output",
                "--privacy_encoding_params_file",
                cobalt_src_dir.join(
                    "src/algorithms/privacy/data/privacy_encoding_params"
                ),
                "--skip_validation",
            ],
        )

        commit_msg = ""
        with api.context(cwd=config_src_dir):
            api.step("checkout head", ["git", "checkout", "-"])
            commit_msg = api.step(
                "read commit message",
                ["git", "show", "-s", "--format=%b"],
                stdout=api.raw_io.output_text(),
            ).stdout

        api.step(
            "validate change",
            [
                build_results.tool("config_change_validator"),
                "--old_config",
                checkout.root_dir.join("old_config"),
                "--new_config",
                checkout.root_dir.join("new_config"),
                "--commit_msg",
                commit_msg,
            ],
        )


def GenTests(api):
    def properties():
        return api.properties(
            remote="https://fuchsia.googlesource.com/manifest",
            manifest="config.manifest",
            fint_params_path="foo/cobalt_config.textproto",
        )

    yield api.buildbucket_util.test("ci", repo="cobalt-registry") + properties()
    yield (
        api.buildbucket_util.test("cq_try", tryjob=True, repo="cobalt-registry")
        + properties()
    )
    yield (
        api.buildbucket_util.test(
            "cq_try_not_cobalt_config", tryjob=True, repo="cobalt"
        )
        + properties()
    )
