#!/usr/bin/env python3
"""
Simple site checker for atlanticsail.net.
Reads configuration from config.json in the same directory.
Logs each attempt to logs/check_YYYY-MM-DD.log.
"""
import json
import os
import sys
import urllib.request
import urllib.error
from datetime import datetime, timezone

SKILL_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_PATH = os.path.join(SKILL_DIR, "config.json")
LOGS_DIR = os.path.join(SKILL_DIR, "logs")
os.makedirs(LOGS_DIR, exist_ok=True)

def load_config():
    defaults = {
        "timeout_seconds": 10,
        "max_retries": 2,
        "failure_threshold": 2
    }
    if not os.path.exists(CONFIG_PATH):
        return defaults.copy()
    try:
        with open(CONFIG_PATH, "r") as f:
            config = json.load(f)
        # Ensure all keys present
        for k, v in defaults.items():
            config.setdefault(k, v)
        return config
    except Exception:
        return defaults.copy()

def save_config(config):
    with open(CONFIG_PATH, "w") as f:
        json.dump(config, f, indent=2)

def log_entry(attempt, total_attempts, status_or_error, outcome):
    timestamp = datetime.now(timezone.utc).isoformat(timespec='seconds')
    log_file = os.path.join(LOGS_DIR, f"check_{datetime.now(timezone.utc).date()}.log")
    with open(log_file, "a") as f:
        f.write(f"{timestamp} | attempt {attempt}/{total_attempts} | {status_or_error} | outcome={outcome}\n")

def check_site(timeout):
    try:
        req = urllib.request.Request("https://atlanticsail.net/", headers={'User-Agent': 'AtlanticSiteMonitor/1.0'})
        with urllib.request.urlopen(req, timeout=timeout) as resp:
            return resp.getcode(), None
    except urllib.error.HTTPError as e:
        return e.code, None
    except urllib.error.URLError as e:
        return None, str(e.reason)
    except Exception as e:
        return None, str(e)

def evolve_config(config, consecutive_successes, consecutive_failures):
    updated = False
    # If too many consecutive failures, increase timeout and retries
    if consecutive_failures >= config["failure_threshold"]:
        if config["timeout_seconds"] < 30:
            config["timeout_seconds"] += 5
            updated = True
        if config["max_retries"] < 5:
            config["max_retries"] += 1
            updated = True
    # If many successes, slowly decrease towards defaults
    if consecutive_successes >= 7:
        if config["timeout_seconds"] > 10:
            config["timeout_seconds"] = max(10, config["timeout_seconds"] - 2)
            updated = True
        if config["max_retries"] > 2:
            config["max_retries"] = max(2, config["max_retries"] - 1)
            updated = True
    return updated

def main():
    config = load_config()
    timeout = config["timeout_seconds"]
    max_retries = config["max_retries"]
    failure_threshold = config["failure_threshold"]

    # Determine recent streak from logs
    consecutive_successes = 0
    consecutive_failures = 0
    today = datetime.now(timezone.utc).date()
    # Look at last 7 days of logs
    for days_back in range(0, 8):
        date = today - datetime.timedelta(days=days_back)
        log_file = os.path.join(LOGS_DIR, f"check_{date}.log")
        if not os.path.exists(log_file):
            continue
        with open(log_file, "r") as f:
            for line in f:
                line = line.strip()
                if not line:
                    continue
                # parse outcome
                if "| outcome=SUCCESS" in line:
                    consecutive_successes += 1
                    consecutive_failures = 0
                elif "| outcome=FAILURE" in line:
                    consecutive_failures += 1
                    consecutive_successes = 0
                else:
                    # Unknown line, reset streaks to be safe
                    consecutive_successes = 0
                    consecutive_failures = 0
        # Stop if we already have enough data to decide (optional)
        if consecutive_successes >= 7 or consecutive_failures >= failure_threshold:
            # we have enough signal; but continue to read all logs for accuracy? We'll break early for speed.
            pass

    # Evolve config based on streaks
    if evolve_config(config, consecutive_successes, consecutive_failures):
        save_config(config)
        # Reload updated values for this run
        config = load_config()
        timeout = config["timeout_seconds"]
        max_retries = config["max_retries"]

    # Perform check with retries
    success = False
    final_status = None
    final_error = None
    for attempt in range(1, max_retries + 1):
        status, error = check_site(timeout)
        if error is None and status == 200:
            success = True
            final_status = status
            break
        else:
            final_status = status
            final_error = error
            # log retry attempt
            log_entry(attempt, max_retries, f"status={status} error={error}" if error else f"status={status}", "RETRY")
            if attempt < max_retries:
                # small delay between retries
                import time
                time.sleep(2)

    outcome = "SUCCESS" if success else "FAILURE"
    log_entry(max_retries if not success else 1, max_retries,
              f"status={final_status} error={final_error}" if not success and final_error else f"status={final_status}",
              outcome)

    # Print summary for user
    if success:
        print(f"✅ Site check PASSED (status {final_status})")
    else:
        print(f"❌ Site check FAILED (status {final_status}) error: {final_error}")
        sys.exit(1)

if __name__ == "__main__":
    main()