#!/usr/bin/env python3

"""
Download and setup SLT (Silicon Labs Tools) CLI for Matter development.

This script downloads and installs the SLT CLI tool which is used to manage
Silicon Labs development tools required for Matter development.
"""

import argparse
import logging
import os
import re
import shutil
import stat
import subprocess
import sys
from zipfile import ZipFile

logger = logging.getLogger(__name__)

try:
    import dload
except ImportError:
    logger.error("dload package is required. Install it with: pip install dload")
    sys.exit(1)


def setup_logging(verbose=False):
    """Configure logging level and format based on verbosity setting."""
    level = logging.DEBUG if verbose else logging.INFO
    logging.basicConfig(level=level, format='[%(levelname)s] %(message)s')


def get_platform_vars():
    """Set platform-specific variables and URLs for SLT CLI download. Linux and macOS only."""
    platform = sys.platform
    if platform == "darwin":
        platform_name = "mac"
    elif platform == "linux":
        platform_name = "linux"
    else:
        logger.error("Platform %s is not supported (Linux and macOS only)", platform)
        sys.exit(1)

    slt_cli_url = f"https://www.silabs.com/documents/public/software/slt-cli-1.1.1-{platform_name}-x64.zip"
    return platform_name, slt_cli_url


def get_tools_path():
    """Return the script directory as the download location."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    os.makedirs(script_dir, exist_ok=True)
    return script_dir


def get_install_done_marker_path():
    """Return path to marker file indicating install-packages has completed successfully."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.join(script_dir, ".install-packages-done")


def get_files_slt_dir():
    """Return path to chip-build-efr32 files-slt directory."""
    repo_root = get_repo_root()
    return os.path.join(
        repo_root, "integrations", "docker", "images", "stage-2", "chip-build-efr32", "files-slt"
    )


def parse_version_from_slt(file_path):
    """Extract dependency version from a .slt file (version = \"X\" in [dependency] block). Returns None if missing."""
    if not file_path or not os.path.isfile(file_path):
        return None
    # This regex finds the [dependency] section and captures the first version string in it.
    pattern = re.compile(r"\[dependency\][^\[]*version\s*=\s*\"([^\"]+)\"")
    try:
        with open(file_path) as f:
            content = f.read()
    except OSError:
        return None
    match = pattern.search(content)
    if match:
        version_str = match.group(1)
        if "." in version_str:
            return version_str.split("@")[0].strip()
    return None


def version_tuple(version_str):
    """Convert version string to tuple of integers for comparison (e.g. 2025.12.2 -> (2025, 12, 2))."""
    if not version_str:
        return ()
    main = version_str.split("-")[0].split("+")[0]
    parts = []
    for p in main.split("."):
        try:
            parts.append(int(p))
        except ValueError:
            parts.append(0)
    return tuple(parts)


def version_greater(a, b):
    """Return True if version string a is greater than b."""
    ta = version_tuple(a)
    tb = version_tuple(b)
    return ta > tb


def read_install_done_versions():
    """Read simplicity_sdk_version and wiseconnect_version from .install-packages-done. Returns None if missing."""
    path = get_install_done_marker_path()
    if not os.path.isfile(path):
        return None
    versions = {}
    try:
        with open(path) as f:
            for line in f:
                line = line.strip()
                if "=" in line:
                    key, _, value = line.partition("=")
                    versions[key.strip()] = value.strip()
    except OSError:
        return None
    simplicity = versions.get("simplicity_sdk_version")
    wiseconnect = versions.get("wiseconnect_version")
    if simplicity is None or wiseconnect is None:
        return None
    return {"simplicity_sdk_version": simplicity, "wiseconnect_version": wiseconnect}


def check_skip_if_up_to_date():
    """
    If .install-packages-done exists, compare its versions to sisdk-pkg.slt and wiseconnect-pkg.slt.
    If both .slt requested versions are not greater than installed, exit 0 (skip execution).
    """
    marker_path = get_install_done_marker_path()
    if not os.path.isfile(marker_path):
        return

    done = read_install_done_versions()
    if done is None:
        return

    files_slt_dir = get_files_slt_dir()
    sisdk_slt = os.path.join(files_slt_dir, "sisdk-pkg.slt")
    wiseconnect_slt = os.path.join(files_slt_dir, "wiseconnect-pkg.slt")

    slt_simplicity = parse_version_from_slt(sisdk_slt)
    slt_wiseconnect = parse_version_from_slt(wiseconnect_slt)

    if slt_simplicity is None:
        logger.error("Could not parse version from %s", sisdk_slt)
        sys.exit(1)
    if slt_wiseconnect is None:
        logger.error("Could not parse version from %s", wiseconnect_slt)
        sys.exit(1)

    need_simplicity = version_greater(slt_simplicity, done["simplicity_sdk_version"])
    need_wiseconnect = version_greater(slt_wiseconnect, done["wiseconnect_version"])

    if not need_simplicity and not need_wiseconnect:
        logger.info(
            "Installed SDK versions (%s, %s) are already >= requested in .slt (%s, %s). Skipping.",
            done["simplicity_sdk_version"],
            done["wiseconnect_version"],
            slt_simplicity,
            slt_wiseconnect,
        )
        sys.exit(0)


def make_executable(path):
    """Make a file executable on Unix-like systems."""
    if path and os.path.exists(path):
        try:
            st = os.stat(path)
            os.chmod(path, st.st_mode | stat.S_IEXEC)
        except OSError as e:
            logger.warning("Could not make %s executable: %s", path, e)
    else:
        logger.warning("Path %s does not exist to make executable.", path)


def download_slt_cli():
    """Download and extract SLT CLI tool to script directory."""
    platform_name, slt_cli_url = get_platform_vars()
    tools_folder_path = get_tools_path()
    slt_cli_path = os.path.join(tools_folder_path, "slt")

    if os.path.isfile(slt_cli_path):
        logger.info("SLT CLI already exists at %s", slt_cli_path)
        return slt_cli_path

    logger.info("Downloading and unzipping slt-cli...")
    slt_zip_path = os.path.join(tools_folder_path, "slt.zip")
    try:
        dload.save(slt_cli_url, slt_zip_path)
        with ZipFile(slt_zip_path, 'r') as zObject:
            # Check for path traversal vulnerabilities before extracting
            for member in zObject.infolist():
                resolved_path = os.path.realpath(os.path.join(tools_folder_path, member.filename))
                if not resolved_path.startswith(os.path.realpath(tools_folder_path)):
                    logger.error("Zip file contains unsafe path: %s", member.filename)
                    sys.exit(1)
            # If all paths are safe, extract
            zObject.extractall(path=tools_folder_path)
        os.remove(slt_zip_path)
        make_executable(slt_cli_path)
        logger.info("SLT CLI installed at %s", slt_cli_path)
        return slt_cli_path
    except Exception as e:
        logger.error("Failed to download/extract slt-cli: %s", e)
        sys.exit(1)


def update_slt_cli(slt_cli_path):
    """Update SLT CLI to latest version."""
    update_cmd = [slt_cli_path, "update", "--self", "--non-interactive"]
    try:
        logger.info("Updating SLT CLI to latest version...")
        subprocess.run(update_cmd, check=True)
        logger.info("SLT CLI updated successfully")
    except subprocess.CalledProcessError as e:
        logger.warning("Failed to update slt-cli: %s", e)
    except FileNotFoundError:
        logger.warning("SLT CLI not found at %s, skipping update", slt_cli_path)


def get_pkg_manifest_paths():
    """Return paths to sisdk-pkg.slt and wiseconnect-pkg.slt from chip-build-efr32 files-slt."""
    repo_root = get_repo_root()
    files_slt_dir = os.path.join(
        repo_root, "integrations", "docker", "images", "stage-2", "chip-build-efr32", "files-slt"
    )
    return [
        os.path.join(files_slt_dir, "wiseconnect-pkg.slt"),
        os.path.join(files_slt_dir, "sisdk-pkg.slt"),
    ]


def install_sdk_packages(slt_cli_path):
    """Install packages from sisdk-pkg.slt and wiseconnect-pkg.slt."""
    for pkg_path in get_pkg_manifest_paths():
        if not os.path.isfile(pkg_path):
            logger.error("Package manifest not found at %s", pkg_path)
            sys.exit(1)

    for pkg_path in get_pkg_manifest_paths():
        install_cmd = [slt_cli_path, "install", "-f", pkg_path, "--non-interactive"]
        try:
            logger.info("Installing packages from %s...", os.path.basename(pkg_path))
            subprocess.run(install_cmd, check=True)
            logger.info("Packages from %s installed successfully", os.path.basename(pkg_path))
        except subprocess.CalledProcessError as e:
            logger.error("Failed to install packages from %s: %s", pkg_path, e)
            sys.exit(1)


def slt_where(slt_cli_path, package):
    """Run 'slt where <package>' and return the path, or None if not found."""
    try:
        result = subprocess.run(
            [slt_cli_path, "where", "--non-interactive", package],
            capture_output=True,
            text=True,
            check=False,
        )
        if result.returncode == 0 and result.stdout.strip():
            # SLT may print interactive prompts to stdout before the actual path.
            # The path may be on its own line or appended after a prompt
            # (e.g. "[y/n]?/home/..."). Scan from the bottom to find it.
            for line in reversed(result.stdout.strip().splitlines()):
                line = line.strip()
                if line.startswith("/"):
                    return line
                # Handle path concatenated after interactive prompt (e.g. "[y/n]?/path" or "[y/n]? /path")
                q_idx = line.rfind("?")
                if q_idx != -1:
                    after = line[q_idx + 1:].lstrip()
                    if after.startswith("/"):
                        return after
            logger.error(
                "Could not find an absolute path in 'slt where %s' output:\n%s",
                package, result.stdout.strip(),
            )
        else:
            logger.error(
                "'slt where %s' failed (exit code %s): %s",
                package, result.returncode, (result.stderr or result.stdout or "").strip(),
            )
    except (subprocess.SubprocessError, FileNotFoundError) as e:
        logger.error("Failed to run 'slt where %s': %s", package, e)
    return None


def get_repo_root():
    """Return the repository root (three levels up from this script)."""
    script_dir = os.path.dirname(os.path.abspath(__file__))
    return os.path.normpath(os.path.join(script_dir, "..", "..", ".."))


SILABS_SDK_LINK_NAMES = ("simplicity_sdk", "wifi_sdk")


def is_git_submodule_checkout(dir_path):
    """Return True if dir_path is a directory that is a git submodule checkout (e.g. from older installs)."""
    if not dir_path or not os.path.isdir(dir_path) or os.path.islink(dir_path):
        return False
    git_file = os.path.join(dir_path, ".git")
    if not os.path.isfile(git_file):
        return False
    try:
        with open(git_file) as f:
            return f.read().strip().startswith("gitdir:")
    except OSError:
        return False


def get_silabs_paths_as_submodules(repo_root):
    """Return which of third_party/silabs/simplicity_sdk and wifi_sdk exist as submodule checkouts on disk."""
    found = []
    for name in SILABS_SDK_LINK_NAMES:
        path = os.path.join(repo_root, "third_party", "silabs", name)
        if is_git_submodule_checkout(path):
            found.append(name)
    return found


def _remove_silabs_submodules(repo_root, submodule_names):
    """Remove submodule checkout dirs: git rm when path is in index; else remove from disk (e.g. after pull, index already has no entry)."""
    paths = [os.path.join("third_party", "silabs", n) for n in submodule_names]
    for path in paths:
        logger.info("Running: git rm %s", path)
        r = subprocess.run(["git", "rm", path], cwd=repo_root, capture_output=True, text=True)
        if r.returncode == 0:
            continue
        full_path = os.path.join(repo_root, path)
        if os.path.isdir(full_path):
            logger.warning("Path not known to Git, removing directory from disk: %s", path)
            try:
                shutil.rmtree(full_path)
            except OSError as e:
                logger.error("Failed to remove %s: %s", path, e)
                sys.exit(1)
        else:
            logger.error("Failed to remove %s: %s", path, r.stderr.strip() or r.stdout.strip())
            sys.exit(1)
    logger.info("Submodules removed successfully.")


def check_silabs_not_submodules(repo_root):
    """If simplicity_sdk or wifi_sdk are submodule checkouts, ask to remove them; else exit with instructions."""
    submodule_names = get_silabs_paths_as_submodules(repo_root)
    if not submodule_names:
        return

    paths = [os.path.join("third_party", "silabs", n) for n in submodule_names]
    logger.warning(
        "The following paths are submodule checkouts (e.g. from older installs): %s. "
        "This script expects to create symlinks here, not use submodules.",
        ", ".join(paths),
    )
    try:
        reply = input("Remove these submodules now? [y/N]: ").strip().lower()
    except EOFError:
        reply = "n"
    if reply in ("y", "yes"):
        _remove_silabs_submodules(repo_root, submodule_names)
    else:
        logger.error(
            "Remove the directories manually (e.g. rm -rf %s), then re-run this script.",
            " ".join(paths),
        )
        sys.exit(1)


def create_sdk_symlinks(simplicity_sdk_path, wiseconnect_path):
    """Create symlinks: third_party/silabs/simplicity_sdk and wifi_sdk to SLT SDK locations."""
    repo_root = get_repo_root()
    silabs_dir = os.path.join(repo_root, "third_party", "silabs")

    def create_symlink(target_path, link_name):
        if not target_path or not os.path.isdir(target_path):
            logger.error(
                "Cannot create symlink: target path does not exist or is not a directory: %s",
                target_path,
            )
            sys.exit(1)
        link_path = os.path.join(silabs_dir, link_name)
        try:
            os.makedirs(silabs_dir, exist_ok=True)
            if os.path.lexists(link_path):
                if os.path.islink(link_path):
                    current = os.path.realpath(link_path)
                    if os.path.realpath(target_path) == current:
                        logger.info("Symlink already up to date: %s", link_path)
                        return  # No error; skip create
                    os.remove(link_path)
                else:
                    logger.error(
                        "Cannot create symlink: %s already exists and is not a symlink. "
                        "Remove it manually and re-run.",
                        link_path,
                    )
                    sys.exit(1)
            os.symlink(target_path, link_path)
            logger.info("Created symlink %s -> %s", link_path, target_path)
        except OSError as e:
            logger.error("Could not create symlink %s -> %s: %s", link_path, target_path, e)
            sys.exit(1)

    create_symlink(simplicity_sdk_path, "simplicity_sdk")
    create_symlink(wiseconnect_path, "wifi_sdk")


def parse_key_from_file(file_path, key):
    """Return the value for the first line 'key: value' in file_path, or None if missing."""
    if not file_path or not os.path.isfile(file_path):
        return None
    prefix = key + ": "
    try:
        with open(file_path) as f:
            for line in f:
                line = line.strip()
                if line.startswith(prefix):
                    return line[len(prefix):].strip()
    except OSError as e:
        logger.warning("Could not read file %s: %s", file_path, e)
    return None


def get_installed_sdk_versions(repo_root):
    """Read sdk_version from simplicity_sdk.slcs and version from wiseconnect.slce under third_party/silabs.
    Exits with an error if either file or key is missing.
    """
    silabs = os.path.join(repo_root, "third_party", "silabs")
    simplicity_slcs = os.path.join(silabs, "simplicity_sdk", "simplicity_sdk.slcs")
    wiseconnect_slce = os.path.join(silabs, "wifi_sdk", "wiseconnect.slce")

    simplicity_sdk_version = parse_key_from_file(simplicity_slcs, "sdk_version")
    wiseconnect_version = parse_key_from_file(wiseconnect_slce, "version")

    missing = []
    if simplicity_sdk_version is None:
        missing.append("sdk_version from %s" % simplicity_slcs)
    if wiseconnect_version is None:
        missing.append("version from %s" % wiseconnect_slce)
    if missing:
        logger.error("Could not read required version fields: %s", "; ".join(missing))
        sys.exit(1)

    return {
        "simplicity_sdk_version": simplicity_sdk_version,
        "wiseconnect_version": wiseconnect_version,
    }


def write_install_done_marker(versions):
    """Write .install-packages-done with installed SDK versions."""
    marker_path = get_install_done_marker_path()
    lines = [f"{key}={value}" for key, value in versions.items()]
    try:
        with open(marker_path, "w") as f:
            f.write("\n".join(lines))
            f.write("\n")
    except OSError as e:
        logger.error("Could not write install-done marker: %s", e)
        sys.exit(1)


def setup_slt_environment(verbose=False):
    """Main function to setup SLT CLI and install required packages."""
    setup_logging(verbose)

    check_skip_if_up_to_date()

    slt_cli_path = download_slt_cli()
    update_slt_cli(slt_cli_path)
    install_sdk_packages(slt_cli_path)

    repo_root = get_repo_root()
    check_silabs_not_submodules(repo_root)

    # Using exact version to avoid ambiguity when multiple versions are installed.
    simplicity_sdk_path = slt_where(slt_cli_path, "simplicity-sdk/2025.12.2")
    wiseconnect_path = slt_where(slt_cli_path, "wiseconnect/4.0.1")
    create_sdk_symlinks(simplicity_sdk_path, wiseconnect_path)

    versions = get_installed_sdk_versions(repo_root)
    write_install_done_marker(versions)

    return slt_cli_path


def main():
    parser = argparse.ArgumentParser(
        description="Download and setup SLT (Silicon Labs Tools) CLI for Matter development."
    )
    parser.add_argument(
        '--verbose', '-v',
        action='store_true',
        help='Enable verbose (debug) logging'
    )
    args = parser.parse_args()

    slt_path = setup_slt_environment(verbose=args.verbose)
    logger.info("\nSLT CLI setup completed successfully")
    logger.info("SLT CLI location: %s", slt_path)


if __name__ == "__main__":
    main()
