package com.foxx.androidcast.stats;

/*********************************************************************
 * SessionStatsStore.java
 * Created at: Sat 16 May 2026 18:50:36 +0200
 * Updated at: Wed 20 May 2026 15:17:13 +0200 by Anton Afanasyeu <a.afanasieff@gmail.com>
 * Commit: 5d8e82d2e60a21fff3138d2a394ee4e8b4c6dcb8
 * class SessionStatsStore
 * Contributors:
 *    - Anton Afanasyeu <a.afanasieff@gmail.com> (3 commits, 117 lines)
 *    - Cursor Agent (project assistant)
 * Digest: SHA256	3f5f4cba05d083cd4387620a0e0a54d00452dc208640c084a125abf60d0ad353
**********************************************************************/
import android.content.Context;

import com.foxx.androidcast.CastConfig;

import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;

/** Rotating flat JSON session logs in app-private storage. */
public final class SessionStatsStore {
    private static final String DIR_NAME = "session_stats";
    /** Legacy captures before schema v2. */
    private static final String PREFIX_LEGACY = "session_";
    public static final String PREFIX_SEND = "session_send_";
    public static final String PREFIX_RECV = "session_recv_";
    private static final String SUFFIX = ".json";

    private SessionStatsStore() {}

    public static File statsDir(Context context) {
        return new File(context.getApplicationContext().getFilesDir(), DIR_NAME);
    }

    private static boolean isSessionJson(String name) {
        if (!name.endsWith(SUFFIX)) {
            return false;
        }
        return name.startsWith(PREFIX_LEGACY)
                || name.startsWith(PREFIX_SEND)
                || name.startsWith(PREFIX_RECV);
    }

    /** Session JSON files, newest first (by filename / start time). */
    public static List<File> listSessionFiles(Context context) {
        File dir = statsDir(context);
        if (!dir.exists()) {
            return Collections.emptyList();
        }
        File[] files = dir.listFiles((d, name) -> isSessionJson(name));
        if (files == null || files.length == 0) {
            return Collections.emptyList();
        }
        List<File> list = new ArrayList<>();
        Collections.addAll(list, files);
        Collections.sort(list, (a, b) -> b.getName().compareTo(a.getName()));
        return list;
    }

    /** Keep at most {@link CastConfig#SESSION_STATS_MAX_FILES} - 1 files before a new session. */
    public static void pruneOnAppStart(Context context) {
        pruneDirectory(statsDir(context), CastConfig.SESSION_STATS_MAX_FILES);
    }

    /** Deletes oldest session JSON files until count is below {@code maxFiles}. */
    static void pruneDirectory(File dir, int maxFiles) {
        if (dir == null || !dir.exists()) {
            return;
        }
        File[] files = dir.listFiles((d, name) -> isSessionJson(name));
        if (files == null || files.length == 0) {
            return;
        }
        List<File> list = new ArrayList<>();
        Collections.addAll(list, files);
        Collections.sort(list, Comparator.comparing(File::getName));
        while (list.size() >= maxFiles) {
            File oldest = list.remove(0);
            if (!oldest.delete()) {
                break;
            }
        }
    }

    public static void saveSession(Context context, long startedMs, String direction, JSONObject json)
            throws Exception {
        File dir = statsDir(context);
        if (!dir.exists() && !dir.mkdirs()) {
            throw new IllegalStateException("Cannot create session_stats dir");
        }
        String prefix = prefixForDirection(direction);
        String name = prefix + formatTimestamp(startedMs) + SUFFIX;
        File out = new File(dir, name);
        byte[] bytes = json.toString(2).getBytes(StandardCharsets.UTF_8);
        try (FileOutputStream fos = new FileOutputStream(out)) {
            fos.write(bytes);
        }
    }

    static String prefixForDirection(String direction) {
        if ("recv".equals(direction)) {
            return PREFIX_RECV;
        }
        return PREFIX_SEND;
    }

    private static String formatTimestamp(long epochMs) {
        return new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date(epochMs));
    }
}
