#!/usr/bin/env python3
"""Host-based intrusion detection agent using OSSEC/Wazuh API and osquery."""

import json
import os
import sys
import argparse
import subprocess
from datetime import datetime

try:
    import requests
    requests.packages.urllib3.disable_warnings()
except ImportError:
    print("Install: pip install requests")
    sys.exit(1)


class WazuhClient:
    """Wazuh API client for HIDS management."""

    def __init__(self, base_url, username, password):
        self.url = base_url.rstrip("/")
        self.token = self._authenticate(username, password)

    def _authenticate(self, username, password):
        resp = requests.post(f"{self.url}/security/user/authenticate",
                             auth=(username, password),
                             verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30)  # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
        resp.raise_for_status()
        return resp.json()["data"]["token"]

    def _get(self, endpoint, params=None):
        resp = requests.get(f"{self.url}/{endpoint}",
                            headers={"Authorization": f"Bearer {self.token}"},
                            params=params,
                            verify=not os.environ.get("SKIP_TLS_VERIFY", "").lower() == "true", timeout=30)  # Set SKIP_TLS_VERIFY=true for self-signed certs in lab environments
        resp.raise_for_status()
        return resp.json()

    def list_agents(self, status=None):
        params = {}
        if status:
            params["status"] = status
        return self._get("agents", params)

    def get_agent_alerts(self, agent_id, limit=20):
        return self._get(f"alerts", {"agent.id": agent_id, "limit": limit})

    def get_sca_results(self, agent_id):
        return self._get(f"sca/{agent_id}")

    def get_rootcheck(self, agent_id):
        return self._get(f"rootcheck/{agent_id}")


def run_osquery_check(query):
    """Execute osquery for host inspection."""
    cmd = ["osqueryi", "--json", query]
    try:
        result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
        return json.loads(result.stdout) if result.stdout.strip() else []
    except (FileNotFoundError, json.JSONDecodeError):
        return [{"error": "osquery not available"}]


def check_file_integrity(paths):
    """Check file integrity for key system files."""
    checks = []
    import hashlib, os
    for path in paths:
        if os.path.exists(path):
            with open(path, "rb") as f:
                sha256 = hashlib.sha256(f.read()).hexdigest()
            stat = os.stat(path)
            checks.append({
                "path": path,
                "sha256": sha256,
                "size": stat.st_size,
                "modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
                "status": "present",
            })
        else:
            checks.append({"path": path, "status": "missing", "severity": "HIGH"})
    return checks


def run_audit(wazuh_url=None, username=None, password=None, agent_id=None):
    """Execute HIDS audit."""
    print(f"\n{'='*60}")
    print(f"  HOST-BASED INTRUSION DETECTION AUDIT")
    print(f"  Generated: {datetime.utcnow().isoformat()} UTC")
    print(f"{'='*60}\n")

    if wazuh_url and username and password:
        client = WazuhClient(wazuh_url, username, password)
        agents = client.list_agents()
        data = agents.get("data", {})
        items = data.get("affected_items", [])
        print(f"--- WAZUH AGENTS ({data.get('total_affected_items', 0)}) ---")
        for a in items[:10]:
            print(f"  {a.get('name', 'N/A')} ({a.get('id', '')}): {a.get('status', '')}")

        if agent_id:
            sca = client.get_sca_results(agent_id)
            sca_data = sca.get("data", {}).get("affected_items", [])
            print(f"\n--- SCA RESULTS (agent {agent_id}) ---")
            for s in sca_data[:5]:
                print(f"  {s.get('name', '')}: pass={s.get('pass', 0)} fail={s.get('fail', 0)}")

    system_files = ["/etc/passwd", "/etc/shadow", "/etc/sudoers", "/etc/ssh/sshd_config"]
    integrity = check_file_integrity(system_files)
    print(f"\n--- FILE INTEGRITY CHECK ---")
    for f in integrity:
        print(f"  {f['path']}: {f['status']}")

    processes = run_osquery_check("SELECT name, pid, uid FROM processes WHERE uid = 0")
    print(f"\n--- ROOT PROCESSES ({len(processes)}) ---")
    for p in processes[:10]:
        if "error" not in p:
            print(f"  PID {p.get('pid', '')}: {p.get('name', '')}")

    return {"integrity": integrity, "processes": processes}


def main():
    parser = argparse.ArgumentParser(description="HIDS Audit Agent")
    parser.add_argument("--wazuh-url", help="Wazuh API URL (https://host:55000)")
    parser.add_argument("--username", help="Wazuh API username")
    parser.add_argument("--password", help="Wazuh API password")
    parser.add_argument("--agent-id", help="Specific agent ID to audit")
    parser.add_argument("--output", help="Save report to JSON file")
    args = parser.parse_args()

    report = run_audit(args.wazuh_url, args.username, args.password, args.agent_id)
    if args.output:
        with open(args.output, "w") as f:
            json.dump(report, f, indent=2, default=str)
        print(f"\n[+] Report saved to {args.output}")


if __name__ == "__main__":
    main()
