import argparse
import json
import sys
import time
import urllib.parse
import urllib.request

DEFAULT_SYMBOLS = ["AAPL", "AMZN", "MSFT", "TSLA"]

REQUIRED_SECTIONS = [
    "key_metrics",
    "valuation",
    "profitability",
    "growth",
    "financial_strength",
    "cashflow",
    "ownership",
    "analyst",
    "earnings",
    "performance",
]

REQUIRED_KEY_METRICS = [
    "previous_close",
    "open",
    "bid",
    "ask",
    "beta",
    "eps_trailing",
    "dividend_rate",
    "current_price",
]


def http_get(base_url, params, timeout):
    query = urllib.parse.urlencode(params)
    url = f"{base_url}?{query}"
    with urllib.request.urlopen(url, timeout=timeout) as resp:
        return json.loads(resp.read().decode("utf-8"))


def parse_list(value, default):
    if not value:
        return default
    return [item.strip() for item in value.split(",") if item.strip()]


def build_signature(data):
    return {
        "key_metrics_keys": sorted(data.get("key_metrics", {}).keys()),
        "valuation_keys": sorted(data.get("valuation", {}).keys()),
        "profitability_keys": sorted(data.get("profitability", {}).keys()),
        "growth_keys": sorted(data.get("growth", {}).keys()),
        "financial_strength_keys": sorted(data.get("financial_strength", {}).keys()),
        "cashflow_keys": sorted(data.get("cashflow", {}).keys()),
        "ownership_keys": sorted(data.get("ownership", {}).keys()),
        "analyst_keys": sorted(data.get("analyst", {}).keys()),
        "earnings_keys": sorted(data.get("earnings", {}).keys()),
        "performance_keys": sorted(data.get("performance", {}).keys()),
    }


def validate_payload(symbol, data):
    if "error" in data:
        return f"API error for {symbol}: {data}"
    if data.get("stock", "").upper() != symbol.upper():
        return f"Symbol mismatch: expected {symbol} got {data.get('stock')}"
    validation = data.get("validation", {})
    if validation.get("symbol_match") is not True:
        return f"Validation symbol_match failed for {symbol}: {validation}"
    if validation.get("issues"):
        return f"Validation issues for {symbol}: {validation}"

    for section in REQUIRED_SECTIONS:
        if section not in data:
            return f"Missing section {section} for {symbol}"

    key_metrics = data.get("key_metrics", {})
    for field in REQUIRED_KEY_METRICS:
        if field not in key_metrics:
            return f"Missing key metric {field} for {symbol}"

    return None


def main():
    parser = argparse.ArgumentParser(description="Yahoo profile scraper test cycles")
    parser.add_argument(
        "--base-url",
        default="http://127.0.0.1:9777/profile",
        help="Base URL for /profile",
    )
    parser.add_argument(
        "--symbols",
        default=",".join(DEFAULT_SYMBOLS),
        help="Comma-separated stock symbols",
    )
    parser.add_argument(
        "--runs",
        type=int,
        default=8,
        help="Number of validation runs per symbol",
    )
    parser.add_argument(
        "--timeout",
        type=int,
        default=180,
        help="Request timeout in seconds",
    )
    parser.add_argument(
        "--sleep",
        type=float,
        default=0.2,
        help="Sleep between requests",
    )
    args = parser.parse_args()

    symbols = parse_list(args.symbols, DEFAULT_SYMBOLS)
    signatures = {}

    print(f"Running {args.runs} profile cycles for: {', '.join(symbols)}")
    for run in range(1, args.runs + 1):
        print(f"Cycle {run}/{args.runs}")
        for symbol in symbols:
            data = http_get(args.base_url, {"stock": symbol}, args.timeout)
            error = validate_payload(symbol, data)
            if error:
                print(f"ERROR: {error}")
                sys.exit(1)
            signature = build_signature(data)
            if symbol not in signatures:
                signatures[symbol] = signature
            elif signatures[symbol] != signature:
                print(f"ERROR: Signature changed for {symbol}")
                print(f"Baseline: {signatures[symbol]}")
                print(f"Current:  {signature}")
                sys.exit(1)
            time.sleep(args.sleep)
        print(f"Cycle {run} OK")

    print("\nAll profile cycles completed successfully.")


if __name__ == "__main__":
    main()
