#!/usr/bin/env python3
"""Docker system audit: collect container diagnostics and return as JSON."""

import json
import os
import subprocess


def cmd(args, parse_json=False):
    try:
        result = subprocess.run(
            args,
            capture_output=True,
            text=True,
            timeout=30,
        )
        out = (result.stdout + result.stderr).strip()

        if parse_json:
            try:
                return json.loads(out) if out else None
            except json.JSONDecodeError:
                return out

        return out

    except Exception as e:
        return f"ERROR: {e}"


def read_file(path):
    try:
        with open(path) as f:
            return f.read().strip().splitlines()
    except FileNotFoundError:
        return None


def main():
    audit = {}

    # Container identity
    audit["container_id"] = os.environ.get("HOSTNAME")
    audit["environment"] = dict(os.environ)

    # OS information inside container
    audit["os_release"] = read_file("/etc/os-release")
    audit["uname"] = cmd(["uname", "-a"])

    # Installed packages (works for Debian/Ubuntu, Alpine, etc.)
    audit["packages"] = {}

    if os.path.exists("/etc/alpine-release"):
        audit["packages"]["manager"] = "apk"
        audit["packages"]["installed"] = cmd(
            ["apk", "info", "-v"]
        ).splitlines()
        audit["packages"]["upgradeable"] = cmd(
            ["apk", "version", "-l", "<"]
        ).splitlines()

    elif os.path.exists("/etc/debian_version"):
        audit["packages"]["manager"] = "dpkg"
        audit["packages"]["installed"] = cmd(
            ["dpkg-query", "-W", "-f=${Package}-${Version}\n"]
        ).splitlines()

    elif os.path.exists("/etc/redhat-release"):
        audit["packages"]["manager"] = "rpm"
        audit["packages"]["installed"] = cmd(
            ["rpm", "-qa"]
        ).splitlines()

    # Docker engine information
    audit["docker_version"] = cmd(
        ["docker", "version", "--format", "{{json .}}"],
        parse_json=True,
    )

    audit["docker_info"] = cmd(
        ["docker", "info", "--format", "{{json .}}"],
        parse_json=True,
    )

    # Containers
    containers = cmd(
        ["docker", "ps", "-a", "--format", "{{json .}}"],
        parse_json=True,
    )

    if isinstance(containers, list):
        audit["docker_containers"] = containers
    else:
        audit["docker_containers"] = []

    # Images
    audit["docker_images"] = cmd(
        ["docker", "images", "--format", "{{json .}}"],
        parse_json=True,
    )

    # Runtime stats
    audit["docker_stats"] = cmd(
        [
            "docker",
            "stats",
            "--no-stream",
            "--format",
            "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}",
        ]
    )

    # Container logs
    logs = {}

    for c in audit["docker_containers"]:
        name = c.get("Names") or c.get("ID")

        if not name:
            continue

        logs[name] = cmd(
            [
                "docker",
                "logs",
                "--tail",
                "100",
                name,
            ]
        )

    audit["docker_logs"] = logs

    # SSH config if present
    audit["sshd_config"] = cmd(
        ["sshd", "-T"]
    ).splitlines()

    # Users
    audit["passwd"] = read_file("/etc/passwd")

    # Runtime info
    audit["uptime"] = cmd(["uptime"])

    # cgroups (useful in Docker)
    audit["cgroup"] = read_file("/proc/self/cgroup")

    # Mounted filesystems
    audit["mounts"] = cmd(["mount"]).splitlines()

    print(json.dumps(audit, indent=2))


if __name__ == "__main__":
    main()
