package cn.skcks.docking.gb28181.mocking.core.sip.message.processor.bye.request;

import cn.skcks.docking.gb28181.core.sip.listener.SipListener;
import cn.skcks.docking.gb28181.core.sip.message.processor.MessageProcessor;
import cn.skcks.docking.gb28181.core.sip.message.subscribe.GenericSubscribe;
import cn.skcks.docking.gb28181.mocking.core.sip.message.subscribe.SipSubscribe;
import cn.skcks.docking.gb28181.mocking.core.sip.response.SipResponseBuilder;
import cn.skcks.docking.gb28181.mocking.core.sip.sender.SipSender;
import gov.nist.javax.sip.message.SIPRequest;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.sip.RequestEvent;
import javax.sip.message.Request;
import javax.sip.message.Response;
import java.util.EventObject;
import java.util.Optional;

@Slf4j
@RequiredArgsConstructor
@Component
public class ByeRequestProcessor implements MessageProcessor {
    private final SipListener sipListener;

    private final SipSubscribe subscribe;

    private final SipSender sender;

    @PostConstruct
    @Override
    public void init() {
        sipListener.addRequestProcessor(Request.BYE, this);
    }

    @Override
    public void process(EventObject eventObject) {
        RequestEvent requestEvent = (RequestEvent) eventObject;
        SIPRequest request = (SIPRequest) requestEvent.getRequest();
        String callId = request.getCallId().getCallId();
        String key = GenericSubscribe.Helper.getKey(Request.BYE, callId);
        String ip = request.getLocalAddress().getHostAddress();
        String transport = request.getTopmostViaHeader().getTransport();
        Optional.ofNullable(subscribe.getByeSubscribe().getPublisher(key))
                .ifPresentOrElse(
                        publisher -> publisher.submit(request),
                        () -> sender.sendResponse(ip, transport, ((provider, ip1, port) ->
                                SipResponseBuilder.response(request, Response.OK, "OK"))));
    }
}
