# 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/jiri",
    "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):
    # Check out the project from the specified manifest.
    with api.context(infra_steps=True):
        build = api.buildbucket.build
        api.checkout.fuchsia_with_options(
            path=api.path["start_dir"], manifest=manifest, remote=remote, build=build,
        )

    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"])
        api.python("build", "./cobaltb.py", args=["build", "--out_dir", tools_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.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.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.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",
        )
    )
