# Copyright 2022 Google LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# version 2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#

# This script uses https://github.com/google/go-licenses to find go dependencies.

import os
import subprocess
from sbom_info_lib import licenses
from sbom_info_lib import license_data

# Max number of processes running in parallel for go-licenses.
PROCESS_LIMIT = 32
GO_LICENSES_TEMPLATE = (
    "/mnt/host/source/src/scripts/hooks/install/sbom_info_lib/go-licenses-template"
)
GO_LICENSES_BIN = "/usr/bin/go-licenses"


def shell_find(path, name):
    return subprocess.run(
        ["find", path, "-type", "f", "-name", name],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )


def find_go_file(path):
    return shell_find(path, "*\\.go").stdout


def get_go_dep(src_path):
    # Check if package contains go file.
    go_files = find_go_file(src_path)
    if not go_files:
        return []

    res = set()
    target_path_list = []
    go_files_list = go_files.decode("utf-8").split("\n")
    for go_file_path in go_files_list:
        if not go_file_path:
            continue
        # go-licenses can fetch collection of libraries
        # used by the package, directly or transitively.
        # So only need to run it on main module.
        with open(go_file_path, "r") as f:
            if "func main()" not in f.read():
                continue
        target_path_list.append(os.path.dirname(go_file_path))
    start_idx = 0
    while start_idx < len(target_path_list):
        p_list = [
            subprocess.Popen(
                [
                    GO_LICENSES_BIN,
                    "report",
                    f"{dir_path}/.",
                    "--template",
                    GO_LICENSES_TEMPLATE,
                ],
                cwd=dir_path,
                stdout=subprocess.PIPE,
                stderr=subprocess.DEVNULL,
            )
            for dir_path in target_path_list[
                start_idx : min(start_idx + PROCESS_LIMIT, len(target_path_list))
            ]
        ]
        start_idx += PROCESS_LIMIT
        for p in p_list:
            output_bytes, _ = p.communicate()
            output = output_bytes.decode("utf-8")
            if not output:
                continue
            for line in output.splitlines():
                if not line:
                    continue
                # Output format: [<pkg_name>@<pkg_version>@<license_name>]
                parts = line.split("@")
                version = parts[1]
                license = parts[2]
                # Top level package e.g. google-guest-agent and packages in
                # vendor/ have version/license "Unknown". They are not needed.
                if version == "Unknown" or license == "Unknown":
                    continue
                if license in licenses.LICENSE_MAP:
                    license = licenses.LICENSE_MAP[license]
                    parts[2] = license
                    line = "@".join(parts)
                elif license not in license_data.SPDX_LICENSES:
                    raise licenses.UnknownLicenseError(
                        f"unknown Go dependency license: {license} in {line}"
                    )
                res.add(line)
    return list(res)
