import requests
import time
import json
import sys

BASE_URL = "http://localhost:8000"

def log_test(name, status, details=""):
    icon = "✅" if status == "PASS" else "❌"
    print(f"{icon} [{name}] - {details}")

def run_api_suite():
    print(f"\n🚀 Starting API Testing Suite (Postman-style logic)\n" + "-"*50)
    
    # 1. AUTHENTICATION TEST
    try:
        login_res = requests.post(f"{BASE_URL}/users/login", json={
            "username": "Admin",
            "password": "admin"
        })
        if login_res.status_code == 200:
            token = login_res.json()["access_token"]
            log_test("Auth: Admin Login", "PASS", f"Status: {login_res.status_code}")
        else:
            log_test("Auth: Admin Login", "FAIL", f"Status: {login_res.status_code}")
            return
    except Exception as e:
        log_test("Auth: Admin Login", "FAIL", str(e))
        return

    headers = {"Authorization": f"Bearer {token}"}

    # 2. STATUS CODES & CRUD
    try:
        item_res = requests.get(f"{BASE_URL}/items/", headers=headers)
        if item_res.status_code == 200:
            log_test("Items: List All", "PASS", f"Returned {len(item_res.json())} items")
        else:
            log_test("Items: List All", "FAIL", f"Status: {item_res.status_code}")
    except Exception as e:
        log_test("Items: List All", "FAIL", str(e))

    # 3. RATE LIMITING TEST (Security Policy)
    print("\n⏳ Testing Rate Limiting (Anti Brute-Force)...")
    limit_hit = False
    for i in range(12): # More than the 5/min limit
        res = requests.post(f"{BASE_URL}/users/login", json={"username": "fake", "password": "fake"})
        if res.status_code == 429:
            limit_hit = True
            log_test("Security: Rate Limiter", "PASS", f"Blocked at attempt {i+1} (429 Too Many Requests)")
            break
    if not limit_hit:
        log_test("Security: Rate Limiter", "FAIL", "Limiter did not trigger after 12 quick requests")

    # 4. RBAC PROTECTION
    # Create a test item to delete
    test_item = requests.post(f"{BASE_URL}/items/", headers=headers, json={
        "barcode": "API-TEST-999",
        "name": "API Test Item",
        "category": "Testing",
        "quantity": 10,
        "min_quantity": 1
    })
    
    if test_item.status_code == 201:
        item_id = test_item.json()["id"]
        log_test("Items: Create test resource", "PASS", f"ID: {item_id}")
        
        # Now try to delete it (as Admin - should pass)
        del_res = requests.delete(f"{BASE_URL}/items/{item_id}", headers=headers)
        if del_res.status_code == 200:
            log_test("RBAC: Admin Delete", "PASS", "Resource purged successfully")
        else:
            log_test("RBAC: Admin Delete", "FAIL", f"Status: {del_res.status_code}")
    else:
        # Check if it already exists from previous failed run
        if test_item.status_code == 400:
             log_test("Items: Create test resource", "PASS", "Resource already exists")
        else:
             log_test("Items: Create test resource", "FAIL", f"Status: {test_item.status_code}")

    # 5. ERROR STATES
    unauth_res = requests.get(f"{BASE_URL}/items/stats")
    if unauth_res.status_code == 401:
        log_test("Security: Unauth Block", "PASS", "Blocked 401 Unauthorized")
    else:
        log_test("Security: Unauth Block", "FAIL", f"Server allowed access! Status: {unauth_res.status_code}")

    print("\n" + "-"*50 + "\n🏁 API Test Suite Finished.")

if __name__ == "__main__":
    run_api_suite()
