from __future__ import annotations

import json
import os
from pathlib import Path


DEFAULT_CONFIG: dict[str, object] = {
    "log_source": "local_syslog",
    "graylog_mcp_url": "",
    "graylog_stream": "",
    "graylog_streams": [],
    "graylog_stream_profiles": [],
    "graylog_query": "*",
    "graylog_fetch_mode": "auto",
    "graylog_tls_verify": True,
    "graylog_range_seconds": 300,
    "graylog_max_events_per_stream": 5000,
    "graylog_raw_sample_events": 5000,
    "graylog_mcp_call_timeout_seconds": 8,
    "graylog_mcp_poll_timeout_seconds": 120,
    "baseline_retention_days": 14,
    "baseline_value_retention_days": 7,
    "baseline_max_values_per_field": 2000,
    "baseline_training_days": 7,
    "graylog_field_mapping": "",
    "llm_enabled": False,
    "llm_model": "",
    "profile_advisor_enabled": False,
    "profile_advisor_model": "qwen3:8b",
    "profile_advisor_timeout": 120,
    "threat_intel_enabled": False,
    "threat_intel_provider": "auto",
    "abuseipdb_api_key": "",
    "virustotal_api_key": "",
    "threat_intel_daily_limit": 100,
    "threat_intel_ttl_seconds": 604800,
    "threat_intel_error_ttl_seconds": 3600,
    "abuseipdb_max_age_days": 90,
}

EDITABLE_FIELDS = set(DEFAULT_CONFIG) | {"graylog_mcp_token"}


class ConfigStore:
    def __init__(self, path: str) -> None:
        self.path = Path(path)

    def read(self) -> dict[str, object]:
        try:
            stored = json.loads(self.path.read_text(encoding="utf-8"))
        except (FileNotFoundError, json.JSONDecodeError, OSError):
            stored = {}
        return {**DEFAULT_CONFIG, **{key: value for key, value in stored.items() if key in EDITABLE_FIELDS}}

    def public(self) -> dict[str, object]:
        config = self.read()
        config["graylog_mcp_token_configured"] = bool(config.pop("graylog_mcp_token", ""))
        config["abuseipdb_api_key_configured"] = bool(config.pop("abuseipdb_api_key", ""))
        config["virustotal_api_key_configured"] = bool(config.pop("virustotal_api_key", ""))
        return config

    def update(self, values: dict[str, object]) -> dict[str, object]:
        current = self.read()
        for key, value in values.items():
            if key not in EDITABLE_FIELDS:
                continue
            if key in {"graylog_mcp_token", "abuseipdb_api_key", "virustotal_api_key"} and value == "":
                continue
            if key in {"llm_enabled", "profile_advisor_enabled", "threat_intel_enabled", "graylog_tls_verify"}:
                current[key] = bool(value)
            elif key == "log_source" and value in {"local_syslog", "graylog_mcp"}:
                current[key] = value
            elif key == "graylog_fetch_mode" and value in {"auto", "raw", "aggregate"}:
                current[key] = value
            elif key in {"graylog_range_seconds", "graylog_max_events_per_stream", "graylog_raw_sample_events", "graylog_mcp_call_timeout_seconds", "graylog_mcp_poll_timeout_seconds", "baseline_retention_days", "baseline_value_retention_days", "baseline_max_values_per_field", "baseline_training_days", "profile_advisor_timeout", "threat_intel_daily_limit", "threat_intel_ttl_seconds", "threat_intel_error_ttl_seconds", "abuseipdb_max_age_days"}:
                try:
                    minimum = 60 if key in {"graylog_range_seconds", "graylog_mcp_poll_timeout_seconds"} else 1
                    current[key] = max(minimum, int(value))
                except (TypeError, ValueError):
                    continue
            elif key == "threat_intel_provider" and value in {"auto", "abuseipdb", "virustotal"}:
                current[key] = value
            elif key == "graylog_streams" and isinstance(value, list):
                streams = [
                    {"id": str(item.get("id", "")), "title": str(item.get("title", "")), "enabled": bool(item.get("enabled"))}
                    for item in value if isinstance(item, dict) and item.get("id")
                ]
                if not streams and current.get("graylog_streams"):
                    continue
                current[key] = streams
            elif key == "graylog_stream_profiles" and isinstance(value, list):
                current[key] = [item for item in value if isinstance(item, dict) and item.get("stream_id")]
            elif isinstance(value, str):
                current[key] = value.strip()
        self.path.parent.mkdir(parents=True, exist_ok=True)
        temporary = self.path.with_suffix(".tmp")
        temporary.write_text(json.dumps(current, indent=2, sort_keys=True), encoding="utf-8")
        os.chmod(temporary, 0o600)
        temporary.replace(self.path)
        return self.public()
