# Copyright 2020 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 goma client binaries."""

from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/git",
    "fuchsia/gn",
    "fuchsia/macos_sdk",
    "fuchsia/ninja",
    "fuchsia/status_check",
    "fuchsia/upload",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/platform",
    "recipe_engine/properties",
    "recipe_engine/python",
    "recipe_engine/step",
]

PROPERTIES = {
    "repository": Property(
        kind=str,
        help="git repository of goma client",
        default="https://chromium.googlesource.com/infra/goma/client",
    ),
    "revision": Property(
        kind=str, help="git revision/branch of goma server repository", default=""
    ),
    "dry_run": Property(
        kind=bool, help="Whether to upload goma client to CIPD.", default=False
    ),
}

GOMA_CLIENT_CIPD_PATH = "fuchsia/third_party/goma/client/${platform}"
DEPOT_TOOLS_GIT = "https://chromium.googlesource.com/chromium/tools/depot_tools.git"
GN_CIPD_PATH = "gn/gn/${platform}"
GN_CIPD_REVISION = "git_revision:222ae505623476f08fd5db3544d7a9e6a0b50472"
NINJA_CIPD_PATH = "infra/ninja/${platform}"
NINJA_CIPD_REVISION = "version:1.9.0"
DEFAULT_FUCHSIA_GOMA_BACKEND = "rbe-prod1.endpoints.fuchsia-infra-goma-prod.cloud.goog"
DEFAULT_FUCHSIA_GOMA_PORT = "8089"
DEFAULT_FUCHSIA_GOMA_IPC = "goma_fuchsia.ipc"
DEFAULT_FUCHSIA_GOMA_SUFFIX = "fuchsia"

SCRIPT_TEST_DATA = """
('COMPILER_PROXY_SOCKET_NAME', 'goma.ipc'),
('COMPILER_PROXY_PORT', '8088'),
ports.append(os.environ.get('GOMA_COMPILER_PROXY_PORT', '8088'))
flags.update({'GOMA_SERVER_HOST': 'clients5.google.com'})
"""


def patch_scripts(api, goma_src_path, py_script):
    # goma_ctl.py has ipc and port number hard coded.
    # rewrite it with Fuchsia spec values.
    input_py = goma_src_path.join("client", py_script)
    api.python(
        name="rewrite %s " % py_script,
        script=api.resource("patch_script.py"),
        args=[
            "--file",
            input_py,
            "--backend",
            DEFAULT_FUCHSIA_GOMA_BACKEND,
            "--ipc_socket",
            DEFAULT_FUCHSIA_GOMA_IPC,
            "--port",
            DEFAULT_FUCHSIA_GOMA_PORT,
        ],
    )


def RunSteps(api, repository, revision, dry_run):
    # Ensure GN
    pkgs = api.cipd.EnsureFile()
    pkgs.add_package(GN_CIPD_PATH, GN_CIPD_REVISION)
    pkgs.add_package(NINJA_CIPD_PATH, NINJA_CIPD_REVISION)
    cipd_dir = api.path["start_dir"].join("cipd")
    api.cipd.ensure(cipd_dir, pkgs)
    api.gn.set_path(cipd_dir.join("gn"))
    api.ninja.set_path(cipd_dir.join("ninja"))

    if not revision:
        gitiles_commit = api.buildbucket.build_input.gitiles_commit
        if (
            "https://%s/%s" % (gitiles_commit.host, gitiles_commit.project)
            == repository
        ):
            revision = gitiles_commit.id
        else:
            revision = "master"

    # Fetch gclient.
    with api.step.nest("fetch gclient"):
        depot_tools_path = api.path["start_dir"].join("depot_tools")
        with api.context(infra_steps=True):
            api.git.checkout(DEPOT_TOOLS_GIT, depot_tools_path)
    # Fetch goma-client
    with api.step.nest("fetch goma-client"):
        goma_client_path = api.path["start_dir"].join("goma")
        goma_src_path = goma_client_path.join("client")
        api.file.ensure_directory("makedirs goma", goma_client_path)

        with api.context(
            infra_steps=True,
            cwd=goma_client_path,
            env_prefixes={"PATH": [depot_tools_path]},
        ):
            api.step(
                "gclient config",
                [
                    "gclient",
                    "config",
                    "--name=client",
                    "--unmanaged",
                    "-v",
                    repository,
                ],
            )
            api.step(
                "gclient sync", ["gclient", "sync",],
            )

            with api.context(cwd=goma_src_path):
                api.git("pin revision", "checkout", revision)
                revision = api.git.get_hash()
                api.step(
                    "gclient sync",
                    ["gclient", "sync", "-v", "--output-json", api.json.output()],
                )

    with api.macos_sdk():
        with api.step.nest("build goma-client"):
            # Build goma
            build_target = "Release"
            build_dir = goma_src_path.join("out").join(build_target)

            gn_args = [
                "is_debug=false",
                'cpu_arch="x64"',
                "enable_revision_check=true",
                "use_link_time_optimization=true",
                'default_server_host="%s"' % DEFAULT_FUCHSIA_GOMA_BACKEND,
                "default_compiler_proxy_port=%s" % DEFAULT_FUCHSIA_GOMA_PORT,
                'default_compiler_proxy_socket_name="%s"' % DEFAULT_FUCHSIA_GOMA_IPC,
                'default_project_suffix="%s"' % DEFAULT_FUCHSIA_GOMA_SUFFIX,
            ]

            patch_scripts(api, goma_src_path, "goma_ctl.py")
            patch_scripts(api, goma_src_path, "goma_auth.py")

            with api.context(cwd=goma_src_path):
                api.gn(
                    "--root=%s" % goma_src_path,
                    "gen",
                    build_dir,
                    "--args=%s" % " ".join(gn_args),
                    name="gn gen",
                )
                # TODO(fxb/71857): fix ninja no-op failure on windows platform.
                api.ninja.build(build_dir, allow_dirty=api.platform.name == "win")
        # Run basic tests
        api.python(
            name="tests",
            script=goma_src_path.join("build", "run_unittest.py"),
            args=[
                "--build-dir",
                goma_src_path.join("out"),
                "--target",
                build_target,
                "--non-stop",
            ],
        )

        # Create archive.
        api.python(
            name="archive",
            script=goma_src_path.join("build", "archive.py"),
            args=[
                "--platform",
                api.platform.name,
                "--build_dir",
                goma_src_path.join("out"),
                "--target_dir",
                build_target,
                "--dist_dir",
                api.path["tmp_base"],
            ],
        )

    # Upload to CIPD
    if not dry_run:
        pkg_dir = build_dir.join("goma-%s" % api.platform.name)
        api.upload.cipd_package(
            GOMA_CLIENT_CIPD_PATH,
            pkg_dir,
            [api.upload.DirectoryPath(pkg_dir)],
            {"git_revision": revision},
            repository,
        )


def GenTests(api):
    yield api.status_check.test("default") + api.buildbucket.ci_build(
        git_repo="https://chromium.googlesource.com/infra/goma/client"
    )
    yield api.status_check.test("dry_run") + api.properties(
        dry_run=True
    ) + api.buildbucket.try_build(
        git_repo="https://fuchsia.googlesource.com/integration"
    )
    yield (
        api.status_check.test("default_with_buildset")
        + api.buildbucket.ci_build(
            bucket="ci",
            git_repo="https://fuchsia.googlesource.com/example",
            revision="a" * 40,
        )
    )
