# 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 generating docs."""

from PB.recipes.fuchsia.docs_roller import InputProperties

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/build",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties

COMMIT_MESSAGE = """\
[gndoc] Update GN build arguments documentation

"""


def RunSteps(api, props):
    gndoc_path = api.cipd.ensure_tool("fuchsia/tools/gndoc/${platform}", "latest")

    checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest,
        remote=props.remote,
    )
    docs_dir = checkout.root_dir.joinpath("docs", "gen")

    gn_args_files = []

    # Generate a GN args JSON file for each build target.
    for target_arch, fint_params_path in sorted(props.fint_params_paths.items()):
        with api.step.nest(target_arch) as presentation:
            gn_results = api.build.gen(
                checkout, fint_params_path, presentation=presentation
            )
            with api.context(cwd=checkout.root_dir):
                gn_args_file = gn_args_json(
                    "gn args --list", api, gn_results, gn_results.build_dir
                )
            # Add targets to final gndoc command
            gn_args_files.append(gn_args_file)

    with api.step.nest("gndoc"), api.context(cwd=checkout.root_dir):
        gndoc(api, gndoc_path, gn_args_files, out_file=docs_dir / "build_arguments.md")

    change = api.auto_roller.attempt_roll(
        api.auto_roller.Options(
            remote="fuchsia.googlesource.com/fuchsia",
        ),
        repo_dir=checkout.root_dir,
        commit_message=COMMIT_MESSAGE,
    )

    return api.auto_roller.raw_result(change)


def gn_args_json(step_name, api, gn_results, build_dir):
    """Return a path to a JSON file containing the GN args."""
    cmd = [gn_results.tool("gn"), "args", build_dir, "--list", "--json"]

    path = api.path.mkstemp("gn-args-json")
    api.step(
        step_name,
        cmd,
        stdout=api.raw_io.output_text(leak_to=path),
        step_test_data=lambda: api.json.test_api.output_stream({}),
    )
    return path


def gndoc(api, gndoc_path, args_files, out_file):
    gndoc_cmd = [
        gndoc_path,
        "-key",
        "target_cpu",
        "-out",
        out_file,
    ]
    for path in args_files:
        gndoc_cmd.extend(["-in", path])

    api.step("gndoc", gndoc_cmd)


def GenTests(api):
    yield (
        api.buildbucket_util.test("basic")
        + api.properties(
            manifest="fuchsia",
            remote="https://fuchsia.googlesource.com/fuchsia",
            fint_params_paths={
                "arm64": "fint_params/docs-roller-arm64.textproto",
                "x64": "fint_params/docs-roller-x64.textproto",
            },
        )
        + api.auto_roller.success()
    )
