#!/usr/bin/env python3

"""
platform-lite: A lightweight, extensible Python script for platform detection.

Supported flags:
  --os                  : Print the OS name (Linux, macos, etc.)
  --version             : Print the OS version (e.g., 20.04, 13.6.3)
  --arch                : Print CPU architecture (e.g., x86_64, aarch64)
  --osnick              : Print a normalized OS codename (e.g., jammy, centos8, sonoma)
  --docker              : Print 1 if inside Docker, else 0 (Linux only)
  --docker-from-osnick  : Print only the osnick (for Docker tag generation)
  --version-artifact    : Print version artifact name mapped from osnick
"""

import argparse
import platform

def parse_args():
    parser = argparse.ArgumentParser(description='Lightweight platform info reporter.')
    parser.add_argument('--os', action='store_true', help='Operating system name')
    parser.add_argument('--osnick', action='store_true', help='OS/distribution codename or nickname')
    parser.add_argument('--version', action='store_true', help='OS version')
    parser.add_argument('--arch', action='store_true', help='System architecture')
    parser.add_argument('--docker', action='store_true', help='Running in a Docker container?')
    parser.add_argument('--docker-from-osnick', action='store_true', help='Guess Docker image from OS nickname')
    parser.add_argument('--version-artifact', action='store_true', help='Mapped version-artifact string')
    parser.add_argument('--debug-version-artifact', metavar='OSNICK', help='Debug: Map given OSNICK to version-artifact')

    return parser.parse_args()

def get_os():
    """Return lowercase OS name (e.g. 'Linux', 'macos')"""
    return platform.system().lower().replace('darwin', 'macos').replace('linux', 'Linux')

def get_arch():
    """Return normalized architecture string"""
    arch = platform.machine().lower()
    return {
        'x86_64': 'x86_64',
        'amd64': 'x64',
        'i386': 'x86',
        'i686': 'x86',
        'aarch64': 'aarch64',
        'arm64': 'aarch64',
        'armv7l': 'arm32v7'
    }.get(arch, arch)

def read_os_release():
    """Parse /etc/os-release into a dictionary (Linux only)"""
    osinfo = {}
    try:
        with open("/etc/os-release") as f:
            for line in f:
                if '=' in line:
                    k, v = line.strip().split('=', 1)
                    osinfo[k] = v.strip('"')
    except FileNotFoundError:
        pass
    return osinfo

def get_macos_nick(version):
    """Map macOS version to codename"""
    macos_nicks = {
    "cheetah":      "1.3",
    "puma":         "1.4",
    "jaguar":       "6",
    "panther":      "7",
    "tiger":        "8",
    "leopard":      "9",
    "snowleopard":  "10",
    "lion":         "11",
    "mountainlion": "12",
    "mavericks":    "13",
    "yosemite":     "14",
    "elcapitan":    "15",
    "sierra":       "16",
    "highsierra":   "17",
    "mojave":       "18",
    "catalina":     "19",
    "bigsur":       "20",
    "monterey":     "21",
    "ventura":      "22",
    "sonoma":       "23",
    "sequoia":      "24",
    }
    macos_nicks = {v: k for k, v in macos_nicks.items()}

    major_minor = '.'.join(version.split('.')[:2])
    if major_minor.startswith("1."):
        return macos_nicks.get(major_minor, f"macos{major_minor}")
    major_minor = version.split('.')[0]
    nick = macos_nicks.get(major_minor, f"macos{major_minor}")
    return nick

def get_osnick(osinfo):
    """
    Generate a short codename or identifier for the platform,
    based on distro ID and version or codename field.
    """
    os_type = get_os()
    if os_type == 'macos':
        version = platform.release()
        return get_macos_nick(version)

    dist = osinfo.get("ID", "")
    codename = osinfo.get("VERSION_CODENAME", "")
    ver = osinfo.get("VERSION_ID", "")
    if dist == "ubuntu":
        return codename or f"{dist}{ver}"
    if dist in ["centos", "ol", "rocky"]:
        return f"{dist}{ver.split('.')[0]}"
    if dist == "alpine":
        return f"{dist}{ver}"
    return codename or f"{dist}{ver}"

def is_docker():
    """Check if running in Docker (Linux-only, uses cgroups)"""
    try:
        with open('/proc/1/cgroup') as f:
            return any('docker' in line for line in f)
    except:
        return False

def map_version_artifact(osnick):
    """Map OS nicknames to version artifact names for Docker images or CI"""
    mappings = {
        "trusty": "ubuntu14.04",
        "xenial": "ubuntu16.04",
        "bionic": "ubuntu18.04",
        "focal": "ubuntu20.04",
        "jammy": "ubuntu22.04",
        "noble": "ubuntu24.04",
        "centos7": "rhel7",
        "centos8": "rhel8",
        "centos9": "rhel9",
        "ol8": "rhel8",
        "rocky8": "rhel8",
        "rocky9": "rhel9",
    }

    # Special mapping: any alpine3.x → alpine3
    if osnick.startswith("alpine3") or osnick.startswith("NotpineForGHA3"):
        return "alpine3"
    return mappings.get(osnick, osnick)

def main():
    args = parse_args()

    # Handle debug option first
    if args.debug_version_artifact:
        print(map_version_artifact(get_macos_nick(args.debug_version_artifact))
)
        return

    os_type = get_os()
    osinfo = read_os_release() if os_type == 'Linux' else {}

    outputs = []

    if args.os:
        outputs.append(os_type)
    if args.version:
        outputs.append(platform.mac_ver()[0] if os_type == 'macos' else osinfo.get("VERSION_ID", "unknown"))
    if args.arch:
        outputs.append(get_arch())
    if args.osnick:
        outputs.append(get_osnick(osinfo))
    if args.docker:
        outputs.append("1" if is_docker() else "0")
    if args.docker_from_osnick:
        print(get_osnick(osinfo))
        return
    if args.version_artifact:
        osnick = get_osnick(osinfo)
        print(map_version_artifact(osnick))
        return

    if outputs:
        print(" ".join(outputs))

if __name__ == "__main__":
    main()
