package com.bsmlab.dfx.agent.listener;

import com.bsmlab.dfx.agent.listener.dto.AckDto;
import com.bsmlab.dfx.agent.listener.service.ListenerService;
import com.bsmlab.dfx.agent.support.ServletUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.Part;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Collection;
import java.util.UUID;

@Slf4j
@RestController
@RequiredArgsConstructor
public class ListenerController {
    private final ListenerService listenerService;

    /**
     * 다른 Agent 에서 수신한 메시지를 저장하고 공유메모리에 등록한다. 메시지 처리는 TaskExecutorService 가 수행한다.
     * @param request
     * @return
     */
    @PostMapping(value = "/listen")
    public AckDto listener(HttpServletRequest request) {
        AckDto ackDto = AckDto.builder().build();
        try {
            String contentType = request.getContentType();
            if(contentType != null && contentType.contains("application/json")) {
                String bodyString = ServletUtils.getBodyString(request);
                log.debug("from: {} receive a  message: {}", request.getRemoteAddr(), bodyString);
                ackDto = listenerService.receiveMessage(bodyString);
            }
            else if(contentType != null && contentType.contains("multipart/form-data")) {
                //파일 전송인 경우 Multipart로 전송하며 파일의 메타데이터인 application/json 과 n개의 파일 본문인 File Multipart 를 합쳐서 전송한다.
                Collection<Part> parts = request.getParts();
                ackDto = listenerService.receiveFiles(parts);
            }
        } catch (IOException | ServletException e) {
            ackDto.setResult(AckDto.ResultType.RECEIVE_FAIL);
            ackDto.setResultText(e.getMessage());
        }
        return ackDto;
    }

    /**
     * 처리 결과(AckDto) 수신
     */
    @PostMapping(value = "/telegram")
    public AckDto telegram(HttpServletRequest request) {
        AckDto ackDto;
        try {
            String bodyString = ServletUtils.getBodyString(request);
            ackDto = listenerService.receiveAck(bodyString);
        } catch (IOException e) {
            ackDto = AckDto.builder().result(AckDto.ResultType.RECEIVE_FAIL).resultText(e.getLocalizedMessage()).messageUuid("").build();
        }
        return ackDto;
    }

    /**
     * agent 상태 점검 등 command 수신
     */
    @PostMapping(value = "/command")
    public AckDto command(HttpServletRequest request) {
        AckDto ackDto;
        try {
            String bodyString = ServletUtils.getBodyString(request);
            ackDto = listenerService.receiveCommand(bodyString);
        } catch (IOException e) {
            ackDto = AckDto.builder().result(AckDto.ResultType.RECEIVE_FAIL).resultText(e.getLocalizedMessage()).messageUuid("").build();
        }
        return ackDto;
    }
}
