package com.ttstd.signaling.store;

import com.ttstd.signaling.model.LoginSession;
import com.ttstd.signaling.model.PrincipalType;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/** 内存实现：不依赖数据库，用于测试与本地演示（storage.mode=memory）。 */
@Component
@Profile("memory")
public class InMemorySessionStore implements SessionStore {

    private final ConcurrentMap<String, LoginSession> sessions = new ConcurrentHashMap<>();

    @Override
    public synchronized LoginSession save(LoginSession session) {
        sessions.put(session.getSessionId(), session);
        return session;
    }

    @Override
    public synchronized Optional<LoginSession> findBySessionId(String sessionId) {
        return Optional.ofNullable(sessions.get(sessionId));
    }

    @Override
    public synchronized List<LoginSession> listByPrincipal(String principalId) {
        return sessions.values().stream()
                .filter(s -> s.getPrincipalId().equals(principalId))
                .collect(Collectors.toList());
    }

    @Override
    public synchronized List<LoginSession> listByPrincipalAndType(String principalId, PrincipalType type) {
        return sessions.values().stream()
                .filter(s -> s.getPrincipalId().equals(principalId) && s.getPrincipalType() == type)
                .collect(Collectors.toList());
    }

    @Override
    public synchronized List<LoginSession> listAll() {
        return List.copyOf(sessions.values());
    }

    @Override
    public synchronized void delete(String sessionId) {
        sessions.remove(sessionId);
    }

    @Override
    public synchronized void deleteByPrincipal(String principalId) {
        sessions.values().removeIf(s -> s.getPrincipalId().equals(principalId));
    }

    @Override
    public synchronized int revokeByPrincipal(String principalId) {
        int n = 0;
        for (LoginSession s : sessions.values()) {
            if (s.getPrincipalId().equals(principalId)) {
                s.setRevoked(true);
                n++;
            }
        }
        return n;
    }

    @Override
    public synchronized int revokeBySessionId(String sessionId) {
        LoginSession s = sessions.get(sessionId);
        if (s != null) {
            s.setRevoked(true);
            return 1;
        }
        return 0;
    }

    @Override
    public synchronized long countByPrincipalAndType(String principalId, PrincipalType type) {
        return sessions.values().stream()
                .filter(s -> s.getPrincipalId().equals(principalId) && s.getPrincipalType() == type)
                .count();
    }
}
