import argparse
import asyncio
import datetime
import sqlite3
import time
import psutil
import httpx

async def check_http(url: str) -> tuple[str, str]:
    """
    Checks the HTTP status of a URL.

    Args:
        url: The URL to check.

    Returns:
        A tuple containing the URL and its status ("OK" or an error message).
    """
    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(url, timeout=5)
            if response.status_code < 400:
                return url, "OK"
            else:
                return url, f"Error: {response.status_code}"
    except httpx.RequestError as e:
        return url, f"Error: {str(e)}"

def check_disk(path: str) -> tuple[str, str]:
    """
    Checks disk usage of a given path.

    Args:
        path: The path to check disk usage.

    Returns:
        A tuple containing the path and its status ("OK" or an error message).
    """
    try:
        disk_usage = psutil.disk_usage(path)
        if disk_usage.percent < 80:
            return path, "OK"
        else:
            return path, f"Warning: {disk_usage.percent}% used"
    except Exception as e:
        return path, f"Error: {str(e)}"

def check_memory() -> tuple[str, str]:
    """
    Checks memory usage.

    Returns:
        A tuple containing "Memory" and its status ("OK" or an error message).
    """
    try:
        memory_usage = psutil.virtual_memory()
        if memory_usage.percent < 80:
            return "Memory", "OK"
        else:
            return "Memory", f"Warning: {memory_usage.percent}% used"
    except Exception as e:
        return "Memory", f"Error: {str(e)}"

def check_cpu() -> tuple[str, str]:
    """
    Checks CPU usage.

    Returns:
        A tuple containing "CPU" and its status ("OK" or an error message).
    """
    try:
        cpu_usage = psutil.cpu_percent(interval=1)
        if cpu_usage < 80:
            return "CPU", "OK"
        else:
            return "CPU", f"Warning: {cpu_usage}% used"
    except Exception as e:
        return "CPU", f"Error: {str(e)}"

def store_results(results: list[tuple[str, str]], db_path: str) -> None:
    """
    Stores the health check results in a SQLite database.

    Args:
        results: A list of tuples containing the service name and its status.
        db_path: The path to the SQLite database.
    """
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    cursor.execute("""
        CREATE TABLE IF NOT EXISTS health_checks (
            timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
            service TEXT,
            status TEXT
        )
    """)

    for service, status in results:
        cursor.execute("INSERT INTO health_checks (service, status) VALUES (?, ?)", (service, status))

    conn.commit()
    conn.close()

async def main(args: argparse.Namespace) -> None:
    """
    Main function to run the health checks and display the status page.
    """
    checks = []
    for url in args.http_urls:
        checks.append(asyncio.create_task(check_http(url)))
    checks.append(asyncio.create_task(check_disk(args.disk_path)))
    checks.append(asyncio.create_task(check_memory()))
    checks.append(asyncio.create_task(check_cpu()))

    results = await asyncio.gather(*checks)

    for service, status in results:
        print(f"{service}: {status}")

    store_results(results, args.db_path)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Health Dashboard")
    parser.add_argument("--http_urls", nargs="+", help="List of HTTP URLs to check")
    parser.add_argument("--disk_path", default="/", help="Path to check disk usage (default: /)")
    parser.add_argument("--db_path", default="health_checks.db", help="Path to the SQLite database (default: health_checks.db)")
    args = parser.parse_args()

    asyncio.run(main(args))