#!/usr/bin/env python3
"""Nexus Autoparts — Post-Installation Health Check

Verifies that all components are running correctly after installation.
Usage: python3 scripts/health_check.py
"""

import sys
import os
import requests
import psycopg2
import redis

# Ensure we can import from project root
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))


def info(msg):
    print(f"[INFO] {msg}")


def ok(msg):
    print(f"[OK]   {msg}")


def fail(msg):
    print(f"[FAIL] {msg}")
    return False


def check_postgresql():
    """Verify PostgreSQL is running and accessible."""
    info("Checking PostgreSQL...")
    try:
        conn = psycopg2.connect("postgresql://nexus@localhost/nexus_autoparts")
        cur = conn.cursor()
        cur.execute("SELECT version()")
        version = cur.fetchone()[0]
        cur.close()
        conn.close()
        ok(f"PostgreSQL running: {version.split()[0]} {version.split()[1]}")
        return True
    except Exception as e:
        return fail(f"PostgreSQL connection failed: {e}")


def check_master_db():
    """Verify master DB has required tables."""
    info("Checking master database schema...")
    try:
        conn = psycopg2.connect("postgresql://nexus@localhost/nexus_autoparts")
        cur = conn.cursor()
        cur.execute("""
            SELECT table_name FROM information_schema.tables
            WHERE table_schema = 'public'
            AND table_name IN ('tenants', 'brands', 'models', 'years', 'part_categories')
        """)
        tables = {r[0] for r in cur.fetchall()}
        cur.close()
        conn.close()

        required = {'tenants', 'brands', 'models', 'years', 'part_categories'}
        missing = required - tables
        if missing:
            return fail(f"Missing master tables: {missing}")
        ok("Master database schema is complete")
        return True
    except Exception as e:
        return fail(f"Master DB check failed: {e}")


def check_tenant_template():
    """Verify tenant_template database exists."""
    info("Checking tenant_template database...")
    try:
        conn = psycopg2.connect("postgresql://nexus@localhost/tenant_template")
        cur = conn.cursor()
        cur.execute("SELECT 1 FROM pg_tables WHERE tablename = 'sales'")
        if not cur.fetchone():
            return fail("tenant_template missing 'sales' table")
        cur.close()
        conn.close()
        ok("tenant_template database exists and has core tables")
        return True
    except Exception as e:
        return fail(f"tenant_template check failed: {e}")


def check_first_tenant():
    """Verify at least one tenant exists."""
    info("Checking first tenant...")
    try:
        conn = psycopg2.connect("postgresql://nexus@localhost/nexus_autoparts")
        cur = conn.cursor()
        cur.execute("SELECT COUNT(*) FROM tenants WHERE is_active = true")
        count = cur.fetchone()[0]
        cur.close()
        conn.close()

        if count == 0:
            return fail("No active tenants found")
        ok(f"Found {count} active tenant(s)")
        return True
    except Exception as e:
        return fail(f"Tenant check failed: {e}")


def check_pos_health():
    """Verify POS health endpoint responds."""
    info("Checking POS health endpoint...")
    try:
        resp = requests.get("http://localhost:5001/pos/health", timeout=5)
        if resp.status_code == 200 and resp.json().get("status") == "ok":
            ok("POS health endpoint is responding")
            return True
        return fail(f"POS health returned: {resp.status_code} {resp.text}")
    except requests.exceptions.ConnectionError:
        return fail("POS not running on port 5001")
    except Exception as e:
        return fail(f"POS health check failed: {e}")


def check_redis():
    """Verify Redis is running and accessible."""
    info("Checking Redis...")
    try:
        r = redis.from_url(
            os.environ.get('REDIS_URL', 'redis://localhost:6379/0'),
            decode_responses=True
        )
        if r.ping():
            info = r.info('server')
            ok(f"Redis {info.get('redis_version', '?')} running")
            return True
        return fail("Redis PING returned False")
    except Exception as e:
        return fail(f"Redis connection failed: {e}")


def check_meilisearch():
    """Verify Meilisearch is running."""
    info("Checking Meilisearch...")
    try:
        sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'pos'))
        from services.meili_search import health_check
        if health_check():
            ok("Meilisearch running")
            return True
        return fail("Meilisearch health check failed")
    except Exception as e:
        return fail(f"Meilisearch connection failed: {e}")


def check_metabase():
    """Verify Metabase is running."""
    info("Checking Metabase...")
    try:
        import requests
        url = os.environ.get('METABASE_URL', 'http://localhost:3000')
        r = requests.get(f"{url}/api/health", timeout=5)
        if r.status_code == 200 and r.json().get('status') == 'ok':
            ok("Metabase running")
            return True
        return fail(f"Metabase returned: {r.status_code}")
    except Exception as e:
        return fail(f"Metabase connection failed: {e}")


def check_web_health():
    """Verify web/dashboard responds."""
    info("Checking web dashboard...")
    try:
        resp = requests.get("http://localhost:5000/", timeout=5)
        if resp.status_code == 200:
            ok("Web dashboard is responding")
            return True
        return fail(f"Web returned status: {resp.status_code}")
    except requests.exceptions.ConnectionError:
        return fail("Web server not running on port 5000")
    except Exception as e:
        return fail(f"Web check failed: {e}")


def main():
    print("=" * 60)
    print("  Nexus Autoparts — Health Check")
    print("=" * 60)
    print()

    results = []
    results.append(("PostgreSQL", check_postgresql()))
    results.append(("Redis Cache", check_redis()))
    results.append(("Meilisearch", check_meilisearch()))
    results.append(("Metabase", check_metabase()))
    results.append(("Master DB Schema", check_master_db()))
    results.append(("Tenant Template", check_tenant_template()))
    results.append(("First Tenant", check_first_tenant()))
    results.append(("POS Health", check_pos_health()))
    results.append(("Web Dashboard", check_web_health()))

    print()
    print("=" * 60)
    passed = sum(1 for _, r in results if r)
    total = len(results)
    print(f"  Results: {passed}/{total} checks passed")
    print("=" * 60)

    if passed < total:
        print()
        print("Failed checks:")
        for name, result in results:
            if not result:
                print(f"  - {name}")
        sys.exit(1)
    else:
        print()
        print("All systems operational!")
        sys.exit(0)


if __name__ == '__main__':
    main()
