# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""Recipe for building Ninja."""

from PB.go.chromium.org.luci.common.proto.srcman.manifest import Manifest

from google.protobuf import json_format

DEPS = [
    "fuchsia/archive",
    "fuchsia/git",
    "fuchsia/macos_sdk",
    "fuchsia/status_check",
    "fuchsia/upload",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/platform",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

GIT_URL = "https://fuchsia.googlesource.com/third_party/github.com/ninja-build/ninja"
CIPD_SERVER_HOST = "chrome-infra-packages.appspot.com"


def RunSteps(api):
    manifest = Manifest()

    with api.step.nest("checkout sources"), api.context(infra_steps=True):
        gitiles_commit = api.buildbucket.build_input.gitiles_commit
        url = (
            "https://%s/%s" % (gitiles_commit.host, gitiles_commit.project)
            if gitiles_commit.host and gitiles_commit.project
            else GIT_URL
        )
        ref = gitiles_commit.id

        src_dir = api.path["start_dir"].join("ninja")
        revision = api.git.checkout(url, path=src_dir, ref=ref)
        git_checkout = manifest.directories[str(src_dir)].git_checkout
        git_checkout.repo_url = url
        git_checkout.revision = revision

    with api.step.nest("ensure packages"), api.context(infra_steps=True):
        cipd_dir = api.path["start_dir"].join("cipd")
        pkgs = api.cipd.EnsureFile()
        pkgs.add_package("fuchsia/third_party/clang/${platform}", "integration")
        if api.platform.is_linux:
            pkgs.add_package(
                "fuchsia/third_party/sysroot/linux",
                "git_revision:47910c0625ad625def7d9e21c9213c91eb9cfa51",
                "sysroot",
            )
        pkgs.add_package(
            "fuchsia/third_party/cmake/${platform}",
            "git_revision:4f90fef85f6391e63dfae26bd6f290c59ea48e95",
        )
        pkgs.add_package(
            "fuchsia/third_party/ninja/${platform}",
            "git_revision:0ccc7886fd4694ae1372d29b4954e2dd3be118be",
        )
        ensured = api.cipd.ensure(cipd_dir, pkgs)
        for subdir, pins in ensured.iteritems():
            directory = manifest.directories[str(cipd_dir.join(subdir))]
            directory.cipd_server_host = CIPD_SERVER_HOST
            for pin in pins:
                directory.cipd_package[pin.package].instance_id = pin.instance_id

    json_manifest = json_format.MessageToJson(
        manifest, preserving_proto_field_name=True
    )
    api.file.write_text(
        "source manifest", src_dir.join("source_manifest.json"), json_manifest
    )

    build_dir = api.path["start_dir"].join("ninja_build_dir")
    api.file.ensure_directory("create build dir", build_dir)

    with api.macos_sdk(), api.context(cwd=build_dir):
        options = [
            "-GNinja",
            "-DCMAKE_C_COMPILER=%s" % cipd_dir.join("bin", "clang"),
            "-DCMAKE_CXX_COMPILER=%s" % cipd_dir.join("bin", "clang++"),
            "-DCMAKE_ASM_COMPILER=%s" % cipd_dir.join("bin", "clang"),
            "-DCMAKE_MAKE_PROGRAM=%s" % cipd_dir.join("ninja"),
            "-DCMAKE_BUILD_TYPE=Release",
            "-DCMAKE_INSTALL_PREFIX=",
        ]

        if api.platform.is_linux:
            options.extend(
                [
                    "-DCMAKE_SYSROOT=%s" % cipd_dir.join("sysroot"),
                    # TODO(phosek): see https://github.com/ninja-build/ninja/issues/1821
                    "-DCMAKE_C_FLAGS=-DUSE_PPOLL",
                    "-DCMAKE_CXX_FLAGS=-DUSE_PPOLL",
                ]
            )
        elif api.platform.is_mac:
            options.extend(
                [
                    "-DCMAKE_SYSROOT=%s"
                    % api.step(
                        "xcrun",
                        ["xcrun", "--sdk", "macosx", "--show-sdk-path"],
                        stdout=api.raw_io.output(name="sdk-path", add_output_log=True),
                        step_test_data=lambda: api.raw_io.test_api.stream_output(
                            "/some/xcode/path"
                        ),
                    ).stdout.strip(),
                ]
                + [
                    "-DCMAKE_%s_LINKER_FLAGS=-nostdlib++ %s"
                    % (mode, cipd_dir.join("lib", "libc++.a"))
                    for mode in ["SHARED", "MODULE", "EXE"]
                ]
            )

        api.step("configure", [cipd_dir.join("bin", "cmake"),] + options + [src_dir])
        api.step("build", [cipd_dir.join("ninja")])
        api.step("test", [cipd_dir.join("ninja"), "test"])

        if api.platform.is_linux:
            api.step(
                "strip",
                [
                    cipd_dir.join("bin", "llvm-objcopy"),
                    "--strip-sections",
                    build_dir.join("ninja"),
                ],
            )
        elif api.platform.is_mac:
            api.step("strip", ["xcrun", "strip", "-x", build_dir.join("ninja")])

    ninja = build_dir.join("ninja" + (".exe" if api.platform.is_win else ""))
    step_result = api.step(
        "ninja version",
        [ninja, "--version"],
        stdout=api.raw_io.output(),
        step_test_data=lambda: api.raw_io.test_api.stream_output("1.9.0.git"),
    )
    ninja_version = step_result.stdout.strip()

    # Upload the installation to isolate.
    api.archive.upload(
        build_dir, [api.upload.FilePath(ninja)], output_property="isolated"
    )

    if api.buildbucket.builder_id.bucket == "prod":
        # Upload the installation to CIPD for production builds.
        api.upload.cipd_package(
            "fuchsia/third_party/ninja/${platform}",
            build_dir,
            [api.upload.FilePath(ninja)],
            {"git_revision": revision},
            repository=url,
            extra_tags={"version": ninja_version},
        )


def GenTests(api):
    for platform in ("linux", "mac", "win"):
        yield (
            api.status_check.test(platform)
            + api.platform.name(platform)
            + api.buildbucket.ci_build(
                project="fuchsia", bucket="prod", git_repo=GIT_URL, revision="a" * 40,
            )
        )
