# 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 publishing tools."""

import re
from PB.recipes.fuchsia.tools import InputProperties

DEPS = [
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/cipd_util",
    "fuchsia/git_checkout",
    "fuchsia/go",
    "recipe_engine/context",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties

# The current list of platforms that we build for.
GO_OS_ARCH = [
    ("linux", "amd64"),
    ("linux", "arm64"),
    ("darwin", "amd64"),
    ("darwin", "arm64"),
]


def RunSteps(api, props):
    if props.manifest:
        checkout_dir = api.checkout.with_options(
            manifest=props.manifest,
            remote=props.remote,
            project=props.project,
        )
        project_info = api.checkout.project(props.project, checkout_root=checkout_dir)
        revision = project_info["revision"]
        project_dir = api.path.abs_to_path(project_info["path"])
    else:
        # If no jiri manifest is specified, checkout with pure git.
        checkout_dir, revision = api.git_checkout(repo=props.remote)
        project_dir = checkout_dir

    staging_dir = api.path.mkdtemp("staging")

    with api.context(cwd=project_dir):
        # Build everything before running tests. Otherwise `go test` will itself
        # do the building and a build error might confusingly be presented as a
        # test error.
        api.go.build(["-v", "./..."])

        with api.step.nest("test"):
            for pkg in api.go.list(
                ["./..."],
                stdout=api.raw_io.output_text(),
                step_test_data=lambda: api.raw_io.test_api.stream_output_text(
                    "go.fuchsia.dev/tools/cmd/gndoc\n"
                    "go.fuchsia.dev/tools/symbolizer/cmd\n"
                ),
            ).stdout.splitlines():
                step = api.go.test(
                    ["-v", "-race", "-cover", pkg],
                    step_name=pkg,
                    stdout=api.raw_io.output_text(name="stdout", add_output_log=True),
                    step_test_data=lambda: api.raw_io.test_api.stream_output_text(
                        f"? {pkg} [no test files]"
                    ),
                )

                # The last line of the verbose output is the one containing the
                # coverage information.
                step.presentation.step_text = coverage_percentage(
                    step.stdout.splitlines()[-1]
                )

        if not props.publish:
            return

        # Publish the main packages to cipd
        for pkg in list_main_packages(api, "./..."):
            with api.step.nest(pkg):
                name = tool_name(pkg)
                for goos, goarch in GO_OS_ARCH + list(
                    props.extra_arch_map.get(name, [])
                ):
                    env = {"GOOS": goos, "GOARCH": goarch}
                    platform = f"{goos.replace('darwin', 'mac')}-{goarch}"
                    with api.context(env=env), api.step.nest(platform):
                        # Rename the tool binary if a renaming is specified.
                        binary_name = props.output_name_map.get(name, name)
                        # Specially handle Windows because using the -o flag
                        # overrides the default behavior of adding the .exe
                        # extension.
                        if goos == "windows":
                            binary_name += ".exe"
                        binary_path = staging_dir / binary_name
                        api.go.build(
                            [
                                "-buildvcs=false",
                                "-trimpath",
                                "-o",
                                binary_path,
                                f"-gcflags=-trimpath={project_dir}",
                                "-ldflags=-s -w -buildid=",
                                pkg,
                            ],
                        )
                        # Upload the outputs.
                        assert props.cipd_root
                        pkg_name_parts = [props.cipd_root]
                        if props.project:
                            pkg_name_parts.append(props.project.split("/")[-1])
                        pkg_name_parts.extend([name, platform])
                        api.cipd_util.upload_package(
                            "/".join(pkg_name_parts),
                            staging_dir,
                            pkg_paths=[binary_path],
                            search_tag={"git_revision": revision},
                            repository=props.remote,
                        )


def list_main_packages(api, path):
    """Returns the 'main' go packages seq(str) on a given path (str)."""
    # Template to pass to `go list` under -f; the listed output will be in that
    # format. See https://golang.org/pkg/cmd/go/internal/list/ for more details.
    # While it might seem cleaner to use the -json list option over templating,
    # the output format is not parsable by python's json.loads()
    list_entry_template = "{{ .ImportPath  }},{{ .Name }}"
    list_entries = api.go.list(
        [
            "-f",
            list_entry_template,
            path,
        ],
        stdout=api.raw_io.output_text(),
        step_test_data=lambda: api.raw_io.test_api.stream_output_text(
            "go.fuchsia.dev/tools/cmd/gndoc,main\n"
            "go.fuchsia.dev/tools/symbolizer/cmd,main\n"
        ),
    ).stdout.splitlines()
    main_packages = []
    for entry in list_entries:
        pkg, name = entry.split(",")
        if name == "main":
            main_packages.append(pkg)
    return tuple(main_packages)


def tool_name(pkg_path):
    """Parses a package's URL to determine the associated tool's name."""
    tokens = pkg_path.split("/")
    if "cmd" in tokens:
        # A package ending in "$name/cmd" should map to a tool named "$name".
        tokens.remove("cmd")
    return tokens[-1]


def coverage_percentage(coverage_line):
    # Regex to match on strings like:
    # 'ok  	go.fuchsia.dev/tools/gndoc	0.002s	coverage: 61.3% of statements'
    coverage_regex = re.compile(
        r"""^ok\s+ # match the initial ok
            \S+\s+ # any sequence of not spaces defines the pkg
            \S+\s+ # execution time
            (.*)$ # capture the last part which must be the coverage
            """,
        re.X,
    )

    match = coverage_regex.match(coverage_line)

    # [no test files] is the same string used by the go tool when a package has
    # no test files
    return match[1] if match else "[no test files]"


def GenTests(api):
    def properties(**kwargs):
        props = {
            "remote": "https://fuchsia.googlesource.com/tools",
            "output_name_map": {"gndoc": "renamed_gndoc"},
        }
        props.update(kwargs)
        return api.properties(**props)

    yield api.buildbucket_util.test("default") + properties()

    yield api.buildbucket_util.test("try", tryjob=True) + properties()

    yield (
        api.buildbucket_util.test("publish__jiri")
        + properties(
            extra_arch_map={"gndoc": [["windows", "amd64"]]},
            publish=True,
            cipd_root="fuchsia",
            manifest="tools",
            project="foo/tools",
        )
    )
