package server.logic.ws_protocol.JSON.debug;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.UUID;

/**
 * Потокобезопасный in-memory буфер debug-логов.
 */
public final class DebugRunLogBuffer {

    public static final class Entry {
        public long ts;
        public String level;
        public String runId;
        public String source;
        public String sessionId;
        public String login;
        public String message;
        public String details;
    }

    private static final DebugRunLogBuffer INSTANCE = new DebugRunLogBuffer(5_000);

    public static DebugRunLogBuffer getInstance() {
        return INSTANCE;
    }

    private final int capacity;
    private final Deque<Entry> entries = new ArrayDeque<>();

    private DebugRunLogBuffer(int capacity) {
        this.capacity = Math.max(100, capacity);
    }

    public synchronized String newRunId() {
        return "dbg-" + UUID.randomUUID();
    }

    public synchronized void clear() {
        entries.clear();
    }

    public synchronized void add(String level, String runId, String source, String sessionId, String login, String message, String details) {
        Entry e = new Entry();
        e.ts = System.currentTimeMillis();
        e.level = safe(level, "info");
        e.runId = safe(runId, "");
        e.source = safe(source, "server");
        e.sessionId = safe(sessionId, "");
        e.login = safe(login, "");
        e.message = safe(message, "");
        e.details = safe(details, "");

        entries.addLast(e);
        while (entries.size() > capacity) {
            entries.removeFirst();
        }
    }

    public synchronized List<Entry> tail(int limit, String runIdFilter) {
        int capped = Math.max(1, Math.min(limit, 1000));
        String filter = safe(runIdFilter, "");

        List<Entry> out = new ArrayList<>(capped);
        Object[] arr = entries.toArray();
        for (int i = arr.length - 1; i >= 0 && out.size() < capped; i--) {
            Entry e = (Entry) arr[i];
            if (!filter.isBlank() && !filter.equals(e.runId)) continue;
            out.add(e);
        }
        return out;
    }

    private static String safe(String value, String fallback) {
        String s = value == null ? "" : value.trim();
        return s.isBlank() ? fallback : s;
    }
}
