#!/usr/bin/env python3
import argparse
import os
import sys
from pathlib import Path

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

from k230_flash import K230FlashTool


def env_flag(name: str, default: bool = False) -> bool:
    value = os.getenv(name)
    if value is None:
        return default
    return value.lower() not in ("0", "false", "no", "off")


def env_int(name: str, default: int) -> int:
    value = os.getenv(name)
    if value is None or value == "":
        return default
    try:
        return int(value)
    except ValueError:
        raise ValueError(f"{name} must be an integer, got: {value}")


def medium(value: str) -> str:
    normalized = value.upper()
    if normalized not in K230FlashTool.VALID_MEDIA:
        raise argparse.ArgumentTypeError(
            f"invalid medium '{value}', expected one of: {', '.join(K230FlashTool.VALID_MEDIA)}"
        )
    return normalized


def main() -> int:
    parser = argparse.ArgumentParser(
        description="Flash a K230 Linux SD-card image through the K230 bootloader."
    )
    parser.add_argument(
        "image",
        nargs="?",
        help="Path to the Linux SD-card image. Defaults to K230_LINUX_IMAGE.",
    )
    parser.add_argument(
        "-m",
        "--medium-type",
        type=medium,
        default=medium(os.getenv("K230_FLASH_MEDIUM", "SDCARD")),
        help="Target medium type (default: SDCARD).",
    )
    parser.add_argument(
        "-d",
        "--device-index",
        default=os.getenv("K230_FLASH_DEVICE", "0"),
        help="Device index used by the external k230-flash tool (default: 0).",
    )
    parser.add_argument(
        "-t",
        "--timeout",
        type=int,
        default=env_int("K230_FLASH_TIMEOUT", 1800),
        help="Flash timeout in seconds; use 0 to disable (default: 1800).",
    )
    parser.add_argument(
        "--boot-timeout",
        type=int,
        default=env_int("K230_BOOTLOADER_TIMEOUT", 10),
        help="Bootloader detection timeout in seconds (default: 10).",
    )
    parser.add_argument(
        "--skip-bootloader-check",
        action="store_true",
        default=env_flag("K230_SKIP_BOOTLOADER_CHECK", False),
        help="Do not reset/probe the board before flashing.",
    )
    parser.add_argument(
        "--no-auto-reboot",
        action="store_true",
        default=not env_flag("K230_FLASH_AUTO_REBOOT", True),
        help="Do not request an automatic reboot after flashing.",
    )

    args = parser.parse_args()

    image = args.image or os.getenv("K230_LINUX_IMAGE")
    if not image:
        print("Error: Linux SD-card image path is required.")
        print("Pass it as an argument or set K230_LINUX_IMAGE.")
        return 1

    image_path = Path(image).expanduser()
    if not image_path.exists():
        print(f"Error: Linux SD-card image not found: {image_path}")
        return 1
    if image_path.is_dir():
        print(f"Error: Linux SD-card image is a directory: {image_path}")
        return 1

    os.environ["K230_FLASH_DEVICE"] = str(args.device_index)

    try:
        # Resolve the uploader before entering the short-lived USB boot ROM window.
        flash_tool = K230FlashTool()

        if not args.skip_bootloader_check:
            from common import ensure_device_in_bootloader

            print("=== Ensuring Device is in Bootloader Mode ===")
            ensure_device_in_bootloader(args.boot_timeout)

        print("=== Flashing K230 Linux SD-card Image ===")
        print(f"Image: {image_path}")
        print(f"Medium: {args.medium_type}")
        print()

        flash_tool.flash(
            image_path=str(image_path),
            medium_type=args.medium_type,
            auto_reboot=not args.no_auto_reboot,
            timeout=None if args.timeout == 0 else args.timeout,
        )
    except KeyboardInterrupt:
        print("\nOperation cancelled by user.")
        return 1
    except Exception as exc:
        print(f"\nError: {exc}")
        return 1

    print("\n=== Linux SD-card Flash Completed Successfully ===")
    return 0


if __name__ == "__main__":
    sys.exit(main())
