# 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 urlparse import urlparse
from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/checkout",
    "fuchsia/goma",
    "fuchsia/jiri",
    "fuchsia/status_check",
    "recipe_engine/buildbucket",
    "recipe_engine/context",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/python",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = {
    "remote": Property(kind=str, help="URL to remote repo containing Jira manifest"),
    "manifest": Property(
        kind=str, help="Jiri manifest file to use, relative to `remote`"
    ),
}


def RunSteps(api, remote, manifest):
    api.goma.ensure()

    # Check out the project from the specified manifest.
    with api.context(infra_steps=True):
        api.checkout.fuchsia_with_options(
            path=api.path["start_dir"], manifest=manifest, remote=remote
        )

    cobalt_config_projects = api.jiri.project(
        ["cobalt-registry"],
        test_data=[
            {
                "name": "cobalt-registry",
                "path": "local/path/to/cobalt-registry",
                "remote": "https://fuchsia.googlesource.com/cobalt-registry",
            },
            {
                "name": "cobalt-registry",
                "path": "other/local/path/to/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(p["remote"]).netloc
            == urlparse(changes[0].host).path.replace("-review", "")
        ]

    # Root of the cobalt repo as checked out by the manifest.
    cobalt_src_dir = api.path["start_dir"].join("third_party/cobalt")
    tools_dir = api.path["start_dir"].join("tools")

    # Build config_parser.
    with api.context(cwd=cobalt_src_dir):
        api.python("setup", "./cobaltb.py", args=["setup"])
        with api.goma.build_with_goma():
            api.python(
                "build",
                "./cobaltb.py",
                args=["build", "--out_dir", tools_dir, "--goma_dir", api.goma.goma_dir],
            )

    config_parser_bin = tools_dir.join("config_parser")
    config_validator_bin = tools_dir.join("config_change_validator")

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

        # Run config_parser on the config repo checkout.
        api.step(
            "check config",
            [
                config_parser_bin,
                "--output_file",
                api.path["start_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",
                api.path["start_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"
                ),
            ],
        )

        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(),
            ).stdout

        api.step(
            "validate change",
            [
                config_validator_bin,
                "--old_config",
                api.path["start_dir"].join("old_config"),
                "--new_config",
                api.path["start_dir"].join("new_config"),
                "--commit_msg",
                commit_msg,
            ],
        )


def GenTests(api):
    yield (
        api.status_check.test("ci")
        + api.buildbucket.ci_build(
            git_repo="https://fuchsia.googlesource.com/cobalt-registry",
        )
        + api.properties(
            remote="https://fuchsia.googlesource.com/manifest",
            manifest="config.manifest",
            project="cobalt-registry",
        )
    )
    yield (
        api.status_check.test("cq_try")
        + api.buildbucket.try_build(
            git_repo="https://fuchsia.googlesource.com/cobalt-registry",
        )
        + api.properties.tryserver(
            remote="https://fuchsia.googlesource.com/manifest",
            manifest="config.manifest",
            project="cobalt-registry",
        )
    )
    yield (
        api.status_check.test("cq_try_not_cobalt_config")
        + api.buildbucket.try_build(git_repo="https://fuchsia.googlesource.com/cobalt",)
        + api.properties.tryserver(
            remote="https://fuchsia.googlesource.com/manifest",
            manifest="config.manifest",
            project="cobalt",
        )
    )
