#!/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 read_env_file(path):
    """Parse a KEY=value env file (optionally quoted) into a dict."""
    env = {}
    try:
        with open(path) as f:
            for line in f:
                line = line.strip()
                if not line or line.startswith("#") or "=" not in line:
                    continue
                if line.startswith("export "):
                    line = line[len("export ") :].strip()
                key, value = line.split("=", 1)
                value = value.strip()
                if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'":
                    value = value[1:-1]
                env[key.strip()] = value
    except (FileNotFoundError, PermissionError):
        pass
    return env


def main():
    audit = {}

    # Provider / contract info (API_KEY is intentionally not exposed)
    server_env = read_env_file("/etc/4server")
    audit["PROVIDER"] = server_env.get("PROVIDER")
    audit["CONTRACT_END"] = server_env.get("CONTRACT_END")
    audit["COST"] = server_env.get("COST")

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

    # 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")

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


if __name__ == "__main__":
    main()
