# Copyright (c) 2024 TOKITA Hiroshi
#
# SPDX-License-Identifier: Apache-2.0

import argparse
import hashlib
import os
import patoolib
import platform
import re
import requests
import semver
import shutil
import subprocess
import tempfile
import textwrap
import zcmake
from pathlib import Path

from west.commands import WestCommand


class Sdk(WestCommand):
    def __init__(self):
        super().__init__(
            "sdk",
            "manage Zephyr SDK",
            "List and Install Zephyr SDK",
        )

    def do_add_parser(self, parser_adder):
        parser = parser_adder.add_parser(
            self.name,
            help=self.help,
            description=self.description,
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog=textwrap.dedent(
                """
            Listing SDKs:

                Run 'west sdk' or 'west sdk list' to list installed SDKs.
                See 'west sdk list --help' for details.


            Installing SDK:

                Run 'west sdk install' to install Zephyr SDK.
                See 'west sdk install --help' for details.
            """
            ),
        )

        subparsers_gen = parser.add_subparsers(
            metavar="<subcommand>",
            dest="subcommand",
            help="select a subcommand. If omitted, treat it as the 'list' selected.",
        )

        subparsers_gen.add_parser(
            "list",
            help="list installed Zephyr SDKs",
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog=textwrap.dedent(
                """
            Listing SDKs:

                Run 'west sdk' or 'west sdk list' command information about available SDKs is displayed.
            """
            ),
        )

        install_args_parser = subparsers_gen.add_parser(
            "install",
            help="install Zephyr SDK",
            formatter_class=argparse.RawDescriptionHelpFormatter,
            epilog=textwrap.dedent(
                """
            Installing SDK:

                Run 'west sdk install' to install Zephyr SDK.

                Set --version option to install a specific version of the SDK.
                If not specified, the install version is detected from "${ZEPHYR_BASE}/SDK_VERSION file.
                SDKs older than 0.14.1 are not supported.

                You can specify the installation directory with --install-dir or --install-base.
                If the specified version of the SDK is already installed,
                the already installed SDK will be used regardless of the settings of
                --install-dir and --install-base.

                Typically, Zephyr SDK archives contain only one directory named zephyr-sdk-<version>
                at the top level.
                The SDK archive is extracted to the home directory if both --install-dir and --install-base
                are not specified.
                In this case, SDK will install into ${HOME}/zephyr-sdk-<version>.
                If --install-base is specified, the archive will be extracted under the specified path.
                In this case, SDK will install into <BASE>/zephyr-sdk-<version> .
                If --install-dir is specified, the directory contained in the archive will be renamed
                and placed to the specified location.

                --interactive, --toolchains, --no-toolchains and --no-hosttools options
                specify the behavior of the installer. Please see the description of each option.

                --personal-access-token specifies the GitHub personal access token.
                This helps to relax the limits on the number of REST API calls.

                --api-url specifies the REST API endpoint for GitHub releases information
                when installing the SDK from a different GitHub repository.
            """
            ),
        )

        install_args_parser.add_argument(
            "--version",
            default=None,
            nargs="?",
            metavar="SDK_VER",
            help="version of the Zephyr SDK to install. "
            "If not specified, the install version is detected from "
            "${ZEPHYR_BASE}/SDK_VERSION file.",
        )
        install_args_parser.add_argument(
            "-b",
            "--install-base",
            default=None,
            metavar="BASE",
            help="Base directory to SDK install. "
            "The subdirectory created by extracting the archive in <BASE> will be the SDK installation directory. "
            "For example, -b /foo/bar will install the SDK in `/foo/bar/zephyr-sdk-<version>'."
        )
        install_args_parser.add_argument(
            "-d",
            "--install-dir",
            default=None,
            metavar="DIR",
            help="SDK install destination directory. "
            "The SDK will be installed on the specified path. "
            "The directory contained in the archive will be renamed and installed for the specified directory. "
            "For example, if you specify -b /foo/bar/baz, The archive's zephyr-sdk-<version> directory will be renamed baz and placed under /foo/bar. "
            "If this option is specified, the --install-base option is ignored. "
        )
        install_args_parser.add_argument(
            "-i",
            "--interactive",
            action="store_true",
            help="launches installer in interactive mode. "
            "--toolchains, --no-toolchains and --no-hosttools will be ignored if this option is enabled.",
        )
        install_args_parser.add_argument(
            "-t",
            "--toolchains",
            metavar="toolchain_name",
            nargs="+",
            help="toolchain(s) to install (e.g. 'arm-zephyr-eabi'). "
            "If this option is not given, toolchains for all architectures will be installed.",
        )
        install_args_parser.add_argument(
            "-T",
            "--no-toolchains",
            action="store_true",
            help="do not install toolchains. "
            "--toolchains will be ignored if this option is enabled.",
        )
        install_args_parser.add_argument(
            "-H",
            "--no-hosttools",
            action="store_true",
            help="do not install host-tools.",
        )
        install_args_parser.add_argument(
            "--personal-access-token", help="GitHub personal access token."
        )
        install_args_parser.add_argument(
            "--api-url",
            default="https://api.github.com/repos/zephyrproject-rtos/sdk-ng/releases",
            help="GitHub releases API endpoint used to look for Zephyr SDKs.",
        )

        return parser

    def os_arch_name(self):
        system = platform.system()
        machine = platform.machine()

        if system == "Linux":
            osname = "linux"
        elif system == "Darwin":
            osname = "macos"
        elif system == "Windows":
            osname = "windows"
        else:
            self.die(f"Unsupported system: {system}")

        if machine in ["aarch64", "arm64"]:
            arch = "aarch64"
        elif machine in ["x86_64", "AMD64"]:
            arch = "x86_64"
        else:
            self.die(f"Unsupported machine: {machine}")

        return (osname, arch)

    def detect_version(self, args):
        if args.version:
            version = args.version
        else:
            if os.environ["ZEPHYR_BASE"]:
                zephyr_base = Path(os.environ["ZEPHYR_BASE"])
            else:
                zephyr_base = Path(__file__).parents[2]

            sdk_version_file = zephyr_base / "SDK_VERSION"

            if not sdk_version_file.exists():
                self.die(f"{str(sdk_version_file)} does not exist.")

            with open(sdk_version_file) as f:
                version = f.readlines()[0].strip()
                self.inf(
                    f"Found '{str(sdk_version_file)}', installing version {version}."
                )

        try:
            semver.Version.parse(version)
        except Exception:
            self.die(f"Invalid version format: {version}")

        if semver.compare(version, "0.14.1") < 0:
            self.die(f"Versions older than v0.14.1 are not supported.")

        return version

    def fetch_releases(self, url, req_headers):
        """fetch releases data via GitHub REST API"""

        releases = []
        page = 1

        while True:
            params = {"page": page, "per_page": 100}
            resp = requests.get(url, headers=req_headers, params=params)
            if resp.status_code != 200:
                raise Exception(f"Failed to fetch: {resp.status_code}, {resp.text}")

            data = resp.json()
            if not data:
                break

            releases.extend(data)
            page += 1

        return releases

    def minimal_sdk_filename(self, release):
        (osname, arch) = self.os_arch_name()
        version = re.sub(r"^v", "", release["tag_name"])

        if semver.compare(version, "0.16.0") < 0:
            if osname == "windows":
                ext = ".zip"
            else:
                ext = ".tar.gz"
        else:
            if osname == "windows":
                ext = ".7z"
            else:
                ext = ".tar.xz"

        return f"zephyr-sdk-{version}_{osname}-{arch}_minimal{ext}"

    def minimal_sdk_sha256(self, sha256_list, release):
        name = self.minimal_sdk_filename(release)
        tuples = [(re.split(r"\s+", t)) for t in sha256_list.splitlines()]
        hashtable = {t[1]: t[0] for t in tuples}

        return hashtable[name]

    def minimal_sdk_url(self, release):
        name = self.minimal_sdk_filename(release)
        assets = release.get("assets", [])
        minimal_sdk_asset = next(filter(lambda x: x["name"] == name, assets))

        return minimal_sdk_asset["browser_download_url"]

    def sha256_sum_url(self, release):
        assets = release.get("assets", [])
        minimal_sdk_asset = next(filter(lambda x: x["name"] == "sha256.sum", assets))

        return minimal_sdk_asset["browser_download_url"]

    def download_and_extract(self, base_dir, dir_name, target_release, req_headers):
        self.inf("Fetching sha256...")
        sha256_url = self.sha256_sum_url(target_release)
        resp = requests.get(sha256_url, headers=req_headers, stream=True)
        if resp.status_code != 200:
            raise Exception(f"Failed to download {sha256_url}: {resp.status_code}")

        sha256 = self.minimal_sdk_sha256(resp.content.decode("UTF-8"), target_release)

        archive_url = self.minimal_sdk_url(target_release)
        self.inf(f"Downloading {archive_url}...")
        resp = requests.get(archive_url, headers=req_headers, stream=True)
        if resp.status_code != 200:
            raise Exception(f"Failed to download {archive_url}: {resp.status_code}")

        try:
            Path(base_dir).mkdir(parents=True, exist_ok=True)

            with tempfile.TemporaryDirectory(dir=base_dir) as tempdir:
                # download archive file
                filename = Path(tempdir) / re.sub(r"^.*/", "", archive_url)
                file = open(filename, mode="wb")
                total_length = int(resp.headers["Content-Length"])
                count = 0

                for chunk in resp.iter_content(chunk_size=8192):
                    file.write(chunk)
                    count = count + len(chunk)
                    self.inf(f"\r {count}/{total_length}", end="")
                self.inf()
                self.inf(f"Downloaded: {file.name}")
                file.close()

                # check sha256 hash
                with open(file.name, "rb") as sha256file:
                    digest = hashlib.sha256(sha256file.read()).hexdigest()
                    if sha256 != digest:
                        raise Exception(f"sha256 mismatched: {sha256}:{digest}")

                # extract archive file
                self.inf(f"Extract: {file.name}")
                patoolib.extract_archive(file.name, outdir=tempdir)

                # We expect that only the zephyr-sdk-x.y.z directory will be present in the archive.
                extracted_dirs = [d for d in Path(tempdir).iterdir() if d.is_dir()]
                if len(extracted_dirs) != 1:
                    raise Exception("Unexpected archive format")

                # move to destination dir
                if dir_name:
                    dest_dir = Path(base_dir / dir_name)
                else:
                    dest_dir = Path(base_dir / extracted_dirs[0].name)

                Path(dest_dir).parent.mkdir(parents=True, exist_ok=True)

                self.inf(f"Move: {str(extracted_dirs[0])} to {dest_dir}.")
                shutil.move(extracted_dirs[0], dest_dir)

                return dest_dir
        except PermissionError as pe:
            self.die(pe)

    def run_setup(self, args, sdk_dir):
        if "Windows" == platform.system():
            setup = Path(sdk_dir) / "setup.cmd"
            optsep = "/"
        else:
            setup = Path(sdk_dir) / "setup.sh"
            optsep = "-"

        # Associate installed SDK so that it can be found.
        cmds_cmake_pkg = [str(setup), f"{optsep}c"]
        self.dbg("Run: ", cmds_cmake_pkg)
        result = subprocess.run(cmds_cmake_pkg)
        if result.returncode != 0:
            self.die(f"command \"{' '.join(cmds_cmake_pkg)}\" failed")

        cmds = [str(setup)]

        if not args.interactive and not args.no_toolchains:
            if not args.toolchains:
                cmds.extend([f"{optsep}t", "all"])
            else:
                for tc in args.toolchains:
                    cmds.extend([f"{optsep}t", tc])

        if not args.interactive and not args.no_hosttools:
            cmds.extend([f"{optsep}h"])

        if args.interactive or len(cmds) != 1:
            self.dbg("Run: ", cmds)
            result = subprocess.run(cmds)
            if result.returncode != 0:
                self.die(f"command \"{' '.join(cmds)}\" failed")

    def install_sdk(self, args, user_args):
        version = self.detect_version(args)
        (osname, arch) = self.os_arch_name()

        if args.personal_access_token:
            req_headers = {
                "Authorization": f"Bearer {args.personal_access_token}",
            }
        else:
            req_headers = {}

        self.inf("Fetching Zephyr SDK list...")
        releases = self.fetch_releases(args.api_url, req_headers)
        self.dbg("releases: ", "\n".join([x["tag_name"] for x in releases]))

        # checking version
        def check_semver(version):
            try:
                semver.Version.parse(version)
                return True
            except Exception:
                return False

        available_versions = [
            re.sub(r"^v", "", x["tag_name"])
            for x in releases
            if check_semver(re.sub(r"^v", "", x["tag_name"]))
        ]

        if not version in available_versions:
            self.die(
                f"Unavailable SDK version: {version}."
                + "Please select from the list below:\n"
                + "\n".join(available_versions)
            )

        target_release = [x for x in releases if x["tag_name"] == f"v{version}"][0]

        # checking toolchains parameters
        assets = target_release["assets"]
        self.dbg("assets: ", "\n".join([x["browser_download_url"] for x in assets]))

        prefix = f"toolchain_{osname}-{arch}_"
        available_toolchains = [
            re.sub(r"\..*", "", x["name"].replace(prefix, ""))
            for x in assets
            if x["name"].startswith(prefix)
        ]

        if args.toolchains:
            for tc in args.toolchains:
                if not tc in available_toolchains:
                    self.die(
                        f"toolchain {tc} is not available.\n"
                        + "Please select from the list below:\n"
                        + "\n".join(available_toolchains)
                    )

        installed_info = [v for (k, v) in self.fetch_sdk_info().items() if k == version]
        if len(installed_info) == 0:
            if args.install_dir:
                base_dir = Path(args.install_dir).parent
                dir_name = Path(args.install_dir).name
            elif args.install_base:
                base_dir = Path(args.install_base)
                dir_name = None
            else:
                base_dir = Path("~").expanduser()
                dir_name = None

            sdk_dir = self.download_and_extract(
                base_dir, dir_name, target_release, req_headers
            )
        else:
            sdk_dir = Path(installed_info[0]["path"])
            self.inf(
                f"Zephyr SDK version {version} is already installed at {str(sdk_dir)}. Using it."
            )

        self.run_setup(args, sdk_dir)

    def fetch_sdk_info(self):
        sdk_lines = []
        try:
            cmds = [
                "-P",
                str(Path(__file__).parent / "sdk" / "listsdk.cmake"),
            ]

            output = zcmake.run_cmake(cmds, capture_output=True)
            if output:
                # remove '-- Zephyr-sdk,' leader
                sdk_lines = [l[15:] for l in output if l.startswith("-- Zephyr-sdk,")]
            else:
                sdk_lines = []

        except Exception as e:
            self.die(e)

        def parse_sdk_entry(line):
            class SdkEntry:
                def __init__(self):
                    self.version = None
                    self.path = None

            info = SdkEntry()
            for ent in line.split(","):
                kv = ent.split("=")
                if kv[0].strip() == "ver":
                    info.version = kv[1].strip()
                elif kv[0].strip() == "dir":
                    info.path = kv[1].strip()

            return info

        sdk_info = {}
        for sdk_ent in [parse_sdk_entry(l) for l in reversed(sdk_lines)]:
            entry = {}

            ver = None
            sdk_path = Path(sdk_ent.path)
            sdk_version_path = sdk_path / "sdk_version"
            if sdk_version_path.exists():
                with open(str(sdk_version_path)) as f:
                    ver = f.readline().strip()
            else:
                continue

            entry["path"] = sdk_path

            if (sdk_path / "sysroots").exists():
                entry["hosttools"] = "installed"

            # Identify toolchain directory by the existence of <toolchain>/bin/<toolchain>-gcc
            if "Windows" == platform.system():
                gcc_postfix = "-gcc.exe"
            else:
                gcc_postfix = "-gcc"

            toolchains = [
                tc.name
                for tc in sdk_path.iterdir()
                if (sdk_path / tc / "bin" / (tc.name + gcc_postfix)).exists()
            ]

            if len(toolchains) > 0:
                entry["toolchains"] = toolchains

            if ver:
                sdk_info[ver] = entry

        return sdk_info

    def list_sdk(self):
        sdk_info = self.fetch_sdk_info()

        if len(sdk_info) == 0:
            self.die("No Zephyr SDK installed.")

        for k, v in sdk_info.items():
            self.inf(f"{k}:")
            self.inf(f"  path: {v['path']}")
            if "hosttools" in v:
                self.inf(f"  hosttools: {v['hosttools']}")
            if "toolchains" in v:
                self.inf("  installed-toolchains:")
                for tc in v["toolchains"]:
                    self.inf(f"    - {tc}")

                # Since version 0.15.2, the sdk_toolchains file is included,
                # so we can get information about available toolchains from there.
                if (Path(v["path"]) / "sdk_toolchains").exists():
                    with open(Path(v["path"]) / "sdk_toolchains") as f:
                        all_tcs = [l.strip() for l in f.readlines()]

                    self.inf("  available-toolchains:")
                    for tc in all_tcs:
                        if tc not in v["toolchains"]:
                            self.inf(f"    - {tc}")

            self.inf()

    def do_run(self, args, user_args):
        self.dbg("args: ", args)
        if args.subcommand == "install":
            self.install_sdk(args, user_args)
        elif args.subcommand == "list" or not args.subcommand:
            self.list_sdk()
