package com.cmvr.quic.gateway.server;

import com.cmvr.quic.gateway.core.ConnectionSession;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.quic.QuicDatagramExtensionEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/** 接收QUIC DATAGRAM，并管理连接级清理与离线事件。 */
final class EdgeConnectionHandler extends SimpleChannelInboundHandler<ByteBuf> {

    private static final Logger log = LoggerFactory.getLogger(EdgeConnectionHandler.class);

    private final ConnectionSession session;
    private ScheduledFuture<?> expirationTask;

    EdgeConnectionHandler(ConnectionSession session) {
        this.session = session;
    }

    @Override
    public void channelActive(ChannelHandlerContext context) throws Exception {
        expirationTask = context.executor().scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                session.expireReassembly();
            }
        }, 500, 500, TimeUnit.MILLISECONDS);
        super.channelActive(context);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext context, ByteBuf datagram) {
        try {
            session.processDatagram(datagram);
        } catch (IllegalArgumentException | IllegalStateException error) {
            log.debug("媒体DATAGRAM已丢弃: {}", error.getMessage());
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext context, Object event) throws Exception {
        if (event instanceof QuicDatagramExtensionEvent) {
            log.debug("QUIC对端已协商DATAGRAM扩展，maxLength={}",
                    ((QuicDatagramExtensionEvent) event).maxLength());
        }
        super.userEventTriggered(context, event);
    }

    @Override
    public void channelInactive(ChannelHandlerContext context) throws Exception {
        if (expirationTask != null) {
            expirationTask.cancel(false);
        }
        session.offline();
        super.channelInactive(context);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext context, Throwable cause) {
        session.fail("QUIC连接处理失败", cause);
    }
}
