"""
Persistent storage for pasted traces in workload local folder.
"""
import dataiku
import re
import threading
from pathlib import Path
from typing import Dict, List, Optional

from traces_explorer.backend.models.trace import Trace
from traces_explorer.backend.services.traces_folder import (
    ManagedTracesFolderService,
    NoStorageTracesFolderService,
    WorkloadTracesFolderService,
)

class PastedTraceStorage:
    """
    Stores pasted traces as JSON files in:
    - workload local folder (default)
    - managed folder
    - no storage (in-memory last trace only)
    """

    def __init__(self, logger, dataiku_api):
        self.logger = logger
        self._lock = threading.Lock()
        self._traces_folder = self._resolve_storage(dataiku_api)

    def _get_storage_prefix(self) -> str:
        user_id = self._get_current_user_id()
        user_folder = self._sanitize_filename(user_id) or "unknown"
        return Path("pasted_traces", user_folder).as_posix()        

    def _resolve_storage(self, dataiku_api):
        config = dataiku_api.webapp_config
        data_storage = config.get("data_storage") or "workload_folder"
        storage_prefix = self._get_storage_prefix()

        if data_storage == "no_storage":
            self.logger.debug("Using no-storage mode for pasted traces")
            return NoStorageTracesFolderService(
                logger=self.logger,
                storage_prefix=storage_prefix,
            )

        if data_storage == "managed_folder":
            managed_folder_id = config.get("managed_folder_id")
            if managed_folder_id:
                try:
                    managed_folder = dataiku.Folder(managed_folder_id)
                    self.logger.debug(
                        "Using managed folder '%s' for pasted traces under '%s'",
                        managed_folder_id,
                        storage_prefix,
                    )
                    return ManagedTracesFolderService(
                        logger=self.logger,
                        managed_folder=managed_folder,
                        storage_prefix=storage_prefix,
                    )
                except Exception as exc:
                    self.logger.warn(
                        "Failed to initialize managed folder '%s', falling back to workload folder: %s",
                        managed_folder_id,
                        exc,
                    )
            else:
                self.logger.warn(
                    "data_storage is managed_folder but managed_folder_id is missing; falling back to workload folder"
                )

        self.logger.debug("Using workload-folder mode for pasted traces")
        return WorkloadTracesFolderService(
            logger=self.logger,
            storage_prefix=storage_prefix,
        )

    def _get_current_user_id(self) -> str:
        try:
            client = dataiku.api_client()
            raw_settings = client.get_own_user().get_settings().get_raw()
            return str(raw_settings.get("login") or "unknown")
        except Exception:
            return "unknown"

    def _sanitize_filename(self, name: Optional[str]) -> str:
        cleaned = re.sub(r"[^A-Za-z0-9._-]+", "_", (name or "").strip())
        cleaned = cleaned.strip("._-")
        return cleaned or "trace"

    def save_trace(self, trace: Trace) -> Optional[str]:
        with self._lock:
            return self._traces_folder.save_trace(
                trace_id=trace.id,
                payload=trace.to_detail_dict(),
            )

    def list_traces(self) -> List[Dict]:
        with self._lock:
            return self._traces_folder.list_traces()

    def delete_trace(self, trace_id: str) -> bool:
        with self._lock:
            return self._traces_folder.delete_trace(trace_id)

    def delete_all(self) -> int:
        with self._lock:
            return self._traces_folder.delete_all()
