package com.tsi.api.server.controller;

import com.tsi.api.server.config.TsiApiServerConfig;
import com.tsi.api.server.controller.result.*;
import com.tsi.api.server.dto.*;
import com.tsi.api.server.error.TscSsipApiErrorCode;
import com.tsi.api.server.repository.TsiSystemStatusManager;
import com.tsi.api.server.service.TscSsipApiService;
import com.tsi.api.server.service.TscSsipKafkaTokenService;
import com.tsi.api.server.util.ApiUtils;
import com.tsi.api.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Slf4j
@RestController
public class TscSsipApiController {

    private final String SSIP_API_NODE_INFO      = "/api/nodeinfo/{apiToken}";
    private final String SSIP_API_BROKER_INFO    = "/api/brokerinfo/{apiToken}";

    private final String SSIP_API_NODE_INFO2     = "/api/nodeInfo/{apiToken}";
    private final String SSIP_API_BROKER_INFO2   = "/api/brokerInfo/{apiToken}";

    private final String SSIP_API_UUID           = "/api/uuid";
    private final String SSIP_API_SYSTEM_STATUS  = "/api/system-status";
    private final String SSIP_API_SYSTEM_STATUS2 = "/api/system-status2";

    private final String SSIP_API_KAFKA_TOKEN    = "/api/kafka/token/{apiToken}";
    private final String SSIP_API_KAFKA_AUTH     = "/api/kafka/auth";

    private final TsiApiServerConfig config;
    private final TscSsipApiService tscSsipApiService;
    private final TscSsipKafkaTokenService tscSsipKafkaTokenService;

    public TscSsipApiController(TsiApiServerConfig config, TscSsipApiService tscSsipApiService, TscSsipKafkaTokenService tscSsipKafkaTokenService) {
        this.config = config;
        this.tscSsipApiService = tscSsipApiService;
        this.tscSsipKafkaTokenService = tscSsipKafkaTokenService;
    }

    @GetMapping(value = "/info", produces = {"application/json; charset=utf8"})
    public String infoString() {
        final String sep = System.lineSeparator();
        final String heading = "----------------------------------------------------------------------------------------------";
        final StringBuilder sb = new StringBuilder();

        sb.append(sep);
        sb.append(heading).append(sep);
        sb.append("TSI API Server Running Information").append(sep);
        sb.append(heading).append(sep);
        sb.append(String.format("Process: %s, Booting: %s, Now: %s",
                this.config.getName(), this.config.getBootingTime(), ApiUtils.now())).append(sep);
        sb.append(heading).append(sep);

        sb.append(heading).append(sep);
        return sb.toString();
    }

    @GetMapping(value = {SSIP_API_NODE_INFO2}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<TscSsipApiResultNodeInfo> getNodeInfo2(@PathVariable("apiToken") String apiToken, HttpServletRequest request) {
        return getNodeInfo(apiToken, request);
    }
    @GetMapping(value = {SSIP_API_BROKER_INFO2}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<TscSsipApiResultBrokerInfo>  getBrokerInfo2(@PathVariable("apiToken") String apiToken, HttpServletRequest request) {
        return getBrokerInfo(apiToken, request);
    }

    @PostMapping(value = {SSIP_API_NODE_INFO}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<TscSsipApiResultNodeInfo> getNodeInfo(@PathVariable("apiToken") String apiToken, HttpServletRequest request) {

        final String apiId = SSIP_API_NODE_INFO;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.info("{}, {}, {}", apiId, remoteIP, apiToken);

        List<NodeDto> resultData = new ArrayList<>();
        ApiInvokeVo apiInvokeVo = ApiInvokeVo.builder()
                .apiId(apiId)
                .apiToken(apiToken)
                .ipAddr(remoteIP)
                .error(TscSsipApiErrorCode.SUCCESS.getCode())
                .build();

        try {
            TscApiResultCode errorCode = this.tscSsipApiService.getTscAuthorizedInfo(apiId, apiToken, remoteIP);
            if (errorCode != TscApiResultCode.SUCCESS) {
                // api token 인증 오류
                log.error("인증오류: [{}] ==> [{}]: [{}].[{}]" + apiId, remoteIP, apiToken, errorCode.getValue(), errorCode.toString());
                apiInvokeVo.setError(errorCode.getValue());
                this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
                //TscSsipApiResultError error = new TscSsipApiResultError(authorizedInfo.getCode(), authorizedInfo.getMessage());
                //return new ResponseEntity<>(new TscSsipApiResultNodeInfo(errorCode, resultData), HttpStatus.UNAUTHORIZED);
                return new ResponseEntity<>(new TscSsipApiResultNodeInfo(errorCode, resultData), HttpStatus.OK);
            }

            List<NodeVo> nodeInfoList = tscSsipApiService.getNodeInfoList();
            nodeInfoList.forEach(obj -> {
                resultData.add(obj.toDto());
            });

            // 이력저장
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            return new ResponseEntity<>(new TscSsipApiResultNodeInfo(errorCode, resultData), HttpStatus.OK);
        }
        catch (Exception e) {
            log.error("getNodeInfo: {}", e.getMessage());
            // 데이터베이스 오류
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            //return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
            TscApiResultCode errorCode = TscApiResultCode.FAIL_INTERNAL_ERROR;
            return new ResponseEntity<>(new TscSsipApiResultNodeInfo(errorCode, resultData), HttpStatus.OK);
        }

//        TscSsipApiResultNodeInfo result = new TscSsipApiResultNodeInfo(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());
//        result.setNodes(tscSsipApiService.getNodeInfoList());
//        result.setCount(result.getNodes().size());

     }

    @PostMapping(value = {SSIP_API_BROKER_INFO}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<TscSsipApiResultBrokerInfo> getBrokerInfo(@PathVariable("apiToken") String apiToken, HttpServletRequest request) {

        final String apiId = SSIP_API_BROKER_INFO;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.info("{}, {}, {}", apiId, remoteIP, apiToken);

        ApiInvokeVo apiInvokeVo = ApiInvokeVo.builder()
                .apiId(apiId)
                .apiToken(apiToken)
                .ipAddr(remoteIP)
                .error(TscSsipApiErrorCode.SUCCESS.getCode())
                .build();

        TscApiResultCode errorCode = null;
        try {
            errorCode = this.tscSsipApiService.getTscAuthorizedInfo(apiId, apiToken, remoteIP);
            if (errorCode != TscApiResultCode.SUCCESS) {
                // api token 인증 오류
                //log.error("인증오류: [{}] ==> [{}]: [{}].[{}]" + apiId, remoteIP, apiToken, authorizedInfo.getCode(), authorizedInfo.getMessage());
                log.error("인증오류: [{}] ==> [{}]: [{}].[{}]" + apiId, remoteIP, apiToken, errorCode.getValue(), errorCode.toString());
                apiInvokeVo.setError(errorCode.getValue());
                this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
                //TscSsipApiResultError error = new TscSsipApiResultError(authorizedInfo.getCode(), authorizedInfo.getMessage());
                //return new ResponseEntity<> (error, HttpStatus.UNAUTHORIZED);
                return new ResponseEntity<>(new TscSsipApiResultBrokerInfo(errorCode, null), HttpStatus.OK);
            }
        }
        catch (Exception e) {
            log.error("getBrokerInfo: {}", e.getMessage());
            // 데이터베이스 오류
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
             //return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
            errorCode = TscApiResultCode.FAIL_INTERNAL_ERROR;
            return new ResponseEntity<>(new TscSsipApiResultBrokerInfo(errorCode, null), HttpStatus.OK);
        }

        try {
            BrokerVo brokerVo = this.tscSsipApiService.getBrokerInfo(apiToken);
            if (brokerVo == null) {
                apiInvokeVo.setError(TscSsipApiErrorCode.NOTFOUND_BROKER_INFO.getCode());
                log.error("{}", apiInvokeVo.toString());
                this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
                errorCode = TscApiResultCode.DATA_NOT_FOUND;
                return new ResponseEntity<>(new TscSsipApiResultBrokerInfo(errorCode, null), HttpStatus.OK);
//                TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.NOTFOUND_BROKER_INFO.getCode(), TscSsipApiErrorCode.NOTFOUND_BROKER_INFO.getMessage());
//                return new ResponseEntity<> (error, HttpStatus.NON_AUTHORITATIVE_INFORMATION);
            }
            // 이력저장
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            //return new ResponseEntity<>(result, HttpStatus.OK);
            return new ResponseEntity<>(new TscSsipApiResultBrokerInfo(errorCode, brokerVo.toDto()), HttpStatus.OK);
        }
        catch (Exception e) {
            log.error("getBrokerInfo: {}", e.getMessage());
            // 데이터베이스 오류
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            //return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
            errorCode = TscApiResultCode.FAIL_INTERNAL_ERROR;
            return new ResponseEntity<>(new TscSsipApiResultBrokerInfo(errorCode, null), HttpStatus.OK);
        }

//        TscSsipApiResultBrokerInfo result = new TscSsipApiResultBrokerInfo(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());
//        result.setBrokerInfo(brokerVo);
//        result.setCount(1);

    }

    @GetMapping(value = {SSIP_API_UUID})
    public String getUUID(){
        String uid = UUID.randomUUID().toString();
        uid = uid.replace("-","").toUpperCase();
        return uid;
    }

    @PostMapping(value = {SSIP_API_SYSTEM_STATUS}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<AbstractTscSsipApiResult> registerSystemStatus(@RequestBody SystemStatusDto status, HttpServletRequest request){

        final String apiId = SSIP_API_SYSTEM_STATUS;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.debug("{}, {}, {}", apiId, remoteIP, status.toString());

        //명목메모리 사용률 = used / total = ( total - free ) / total
        //실질메모리 사용률 = used2 / total = ( total - free2[2] ) / total = ( total - free - buffers - cached) / total
        //free 열의 두번째 행이 실질적인 유휴메모리 용량이다.
        //[root@localhost1 ~]# free
        //             total       used       free     shared    buffers     cached
        //Mem:       1016828     933428      83400      31380      63516     536812
        //-/+ buffers/cache:     333100     683728
        //Swap:       524284       1984     522300
        //전체 용량 = 1016828
        //명목 여유 메모리 = 83400
        //실질 여유 메모리 = 683728 ( = 83400 + 63516 + 536812 )
        SystemStatusVo vo = TsiSystemStatusManager.getInstance().get(status.getHostName());
        if (vo == null) {
            vo = new SystemStatusVo();
            vo.setHostName(status.getHostName());
            TsiSystemStatusManager.getInstance().put(status.getHostName(), vo);
        }
        try {
            vo.setOsType(status.getOsType());
            vo.setOsName(status.getOsName());
            vo.setOsType(status.getOsType());
            vo.setOsVersion(status.getOsVersion());
            vo.setOsArch(status.getOsArch());
            vo.setKernelRelease(status.getKernelRelease());
            vo.setInternalIp(status.getInternalIp());
            vo.setExternalIp(status.getExternalIp());
            vo.setSwapMem(status.getSwapMem()); // long
            vo.setCpuCnt(status.getCpuCnt());
            vo.setUpTimes(status.getUpTimes());

            vo.setUseCpuRate(status.getUseCpuRate());
            vo.setTasks(status.getTasks());
            vo.setThreads(status.getThreads());
            vo.setLoadAvg(status.getLoadAvg());

            // disk
            if (status.getTotalDisk() > 0) {
                double dblTotal = status.getTotalDisk();
                double dblUsed = status.getUsedDisk();
                status.setUseDiskRate((float)((dblUsed/dblTotal)*100.0));
                if (status.getUseDiskRate() > 100.0) {
                    status.setUseDiskRate(100);
                }
                status.setTotalDisk(status.getTotalDisk()/1024);    // KB => MB

                vo.setTotalDisk((float)(dblTotal/1024/1024));
                vo.setUseDisk((float)(dblUsed/1024/1024));
                vo.setUseDiskRate(status.getUseDiskRate());
            }
            // swap
            float total;
            float used;
            if (status.getSwapMem() > 0 && status.getUsedSwap() > 0) {
                total = (float)status.getSwapMem();
                used = (float)status.getUsedSwap();
                status.setUseSwapRate((float)((used/total) * 100.0));
                if (status.getUsedSwap() > 100.0) {
                    status.setUseSwapRate(100);
                }
            }

            // memory
            if (status.getTotalMem() > 0) {
                total = (float)status.getTotalMem();
                // 명목
                used = total - status.getFreeMem();
                status.setUseMemRate((float)((used/total) * 100.0));       // calculate
                if (status.getUseMemRate() > 100.0) {
                    status.setUseMemRate(100);
                }
                // 실질
                used = total - status.getFreeMem() - status.getCacheMem();
                status.setRealMemRate((float)((used/total) * 100.0));       // calculate
                if (status.getRealMemRate() > 100.0) {
                    status.setRealMemRate(100);
                }

                vo.setTotalMem(total/1024);
                vo.setUseMem(used/1024);
                vo.setUseMemRate(status.getRealMemRate());
            }
            vo.setUpdateTm(System.currentTimeMillis());
            vo.setUpdate(true);

            //this.tscSsipApiService.insertSystemStatusHs(vo);
            //this.tscSsipApiService.updateSystemInfo(status);
        }
        catch(Exception e) {
            log.error("{}", e.getMessage().toString());
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            return new ResponseEntity<> (error, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        TscSsipApiResultSystemStatus result = new TscSsipApiResultSystemStatus(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());
        result.setResult("ok");
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping(value = {SSIP_API_SYSTEM_STATUS2}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<AbstractTscSsipApiResult> registerSystemStatus2(@RequestBody SystemStatus2Dto status, HttpServletRequest request){

        final String apiId = SSIP_API_SYSTEM_STATUS2;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.debug("{}, {}, {}", apiId, remoteIP, status.toString());

        //명목메모리 사용률 = used / total = ( total - free ) / total
        //실질메모리 사용률 = used2 / total = ( total - free2[2] ) / total = ( total - free - buffers - cached) / total
        //free 열의 두번째 행이 실질적인 유휴메모리 용량이다.
        //[root@localhost1 ~]# free
        //             total       used       free     shared    buffers     cached
        //Mem:       1016828     933428      83400      31380      63516     536812
        //-/+ buffers/cache:     333100     683728
        //Swap:       524284       1984     522300
        //전체 용량 = 1016828
        //명목 여유 메모리 = 83400
        //실질 여유 메모리 = 683728 ( = 83400 + 63516 + 536812 )
        SystemStatusVo vo = TsiSystemStatusManager.getInstance().get(status.getHostName());
        if (vo == null) {
            vo = new SystemStatusVo();
            vo.setHostName(status.getHostName());
            TsiSystemStatusManager.getInstance().put(status.getHostName(), vo);
        }

        try {
            // cpu
            vo.setUseCpuRate(status.getCpuLoad());
            vo.setLoadAvg(status.getCpuLoad());
            // disk
            vo.setUseDiskRate(status.getDisUsage());
            // memory
            vo.setUseMemRate(status.getMemoryUsage());

            vo.setUpdateTm(System.currentTimeMillis());
            vo.setUpdate(true);
        }
        catch(Exception e) {
            log.error("{}", e.getMessage().toString());
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            return new ResponseEntity<> (error, HttpStatus.INTERNAL_SERVER_ERROR);
        }
        TscSsipApiResultSystemStatus result = new TscSsipApiResultSystemStatus(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());
        result.setResult("ok");
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @GetMapping(value = {SSIP_API_KAFKA_TOKEN}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<AbstractTscSsipApiResult> getKafkaToken(@PathVariable("apiToken") String apiToken, HttpServletRequest request) {

        final String apiId = SSIP_API_KAFKA_TOKEN;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.info("{}, {}, {}", apiId, remoteIP, apiToken);

        ApiInvokeVo apiInvokeVo = ApiInvokeVo.builder()
                .apiId(apiId)
                .apiToken(apiToken)
                .ipAddr(remoteIP)
                .error(TscSsipApiErrorCode.SUCCESS.getCode())
                .build();

        KafkaAuthorizedVo authorizedVo = null;
        try {
            authorizedVo = this.tscSsipApiService.getKafkaAuthorizedInfo(apiToken, remoteIP, true);
            if (authorizedVo.getErrorCode() != TscSsipApiErrorCode.SUCCESS) {
                // api token 인증 오류
                log.error("인증오류: [{}] ==> [{}]: [{}].[{}]" + apiId, remoteIP, apiToken, authorizedVo.getErrorCode(), authorizedVo.getErrorCode().getMessage());
                apiInvokeVo.setError(authorizedVo.getErrorCode().getCode());
                this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
                TscSsipApiResultError error = new TscSsipApiResultError(authorizedVo.getErrorCode().getCode(), authorizedVo.getErrorCode().getMessage());
                return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
            }
        }
        catch (Exception e) {
            log.error("tscSsipKafkaTokenService: {}", e.getMessage());
            // 데이터베이스 오류
            TscSsipApiResultError error = new TscSsipApiResultError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode(), TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);
        }

        KafkaTokenDto token = this.tscSsipKafkaTokenService.generateToken(apiToken, authorizedVo.getBrokerId(), authorizedVo.getBrokerPwd(), "KAFKA");
        TscSsipApiResultKafkaTokenInfo result = new TscSsipApiResultKafkaTokenInfo(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());
        result.setAccessToken(token.getToken());
        result.setCount(1);

        // 이력저장
        this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

    @PostMapping(value = {SSIP_API_KAFKA_AUTH}, produces = {"application/json; charset=utf8"})
    public ResponseEntity<AbstractTscSsipApiResult> getKafkaAuth(@RequestBody KafkaTokenAuthDto token, HttpServletRequest request) {

        final String apiId = SSIP_API_KAFKA_AUTH;
        final String remoteIP = ApiUtils.getRemoteIP(request);
        log.info("{}, {}, {}", apiId, remoteIP, token);

        String resultCode = String.valueOf(TscSsipApiErrorCode.SUCCESS.getCode());
        TscSsipApiResultKafkaAuth result = new TscSsipApiResultKafkaAuth(TscSsipApiErrorCode.SUCCESS.getCode(), TscSsipApiErrorCode.SUCCESS.getMessage());

        ApiInvokeVo apiInvokeVo = ApiInvokeVo.builder()
                .apiId(apiId)
                .apiToken(token.getApiToken())
                .ipAddr(remoteIP)
                .error(TscSsipApiErrorCode.SUCCESS.getCode())
                .build();

        KafkaAuthorizedVo authorizedVo = null;
        try {
            authorizedVo = this.tscSsipApiService.getKafkaAuthorizedInfo(token.getApiToken(), remoteIP, false);
            if (authorizedVo.getErrorCode() != TscSsipApiErrorCode.SUCCESS) {
                // api token 인증 오류
                log.error("인증오류: [{}] ==> [{}]: [{}].[{}]" + apiId, remoteIP, token.getApiToken(), authorizedVo.getErrorCode(), authorizedVo.getErrorCode().getMessage());
                apiInvokeVo.setError(authorizedVo.getErrorCode().getCode());
                this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
                TscSsipApiResultError error = new TscSsipApiResultError(authorizedVo.getErrorCode().getCode(), authorizedVo.getErrorCode().getMessage());
                return new ResponseEntity<>(error, HttpStatus.UNAUTHORIZED);
            }
        }
        catch (Exception e) {
            log.error("Exception: {}", e.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            resultCode = String.valueOf(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            result.setResult(resultCode);
            this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
            return new ResponseEntity<>(result, HttpStatus.OK);
        }
/*
        SUCCESS              (0,"요청성공"),
                UNREGISTERED_APITOKEN(1,"등록되지 않은 API TOKEN"),
                APITOKEN_EXPIRED     (2,"API TOKEN 유효기간 오류"),
                DENIED_IPADDR        (3,"접근불가 IP Address"),
                NOTFOUND_BROKER_INFO (4,"접속 가능한 브로커 정보가 없음"),
                NOTFOUND_URL         (5,"잘못된 URL 경로"),
                ERROR_INTERNAL_DATA  (6,"내부 데이터 오류"),
                NOT_AVAILABLE        (7,"현재 사용할수 없음"),       // useyn='N'
                PENDING_REGISTRATION (8,"등록 대기 중");             // Navi Device, 등록 대기중 useyn='Y', state='R'
*/

        try {
            log.info("token.getAccessToken(): {}", token.getAccessToken());
            if (token.getAccessToken() != null && this.tscSsipKafkaTokenService.verifyToken(token.getAccessToken())) {
                KafkaTokenDto tokenDto = this.tscSsipKafkaTokenService.decode(token.getAccessToken());
                log.info("tokenDto: {}", tokenDto);
                if (tokenDto.getApiToken() != null && tokenDto.getApiToken().equals(token.getApiToken())) {
                    log.info("getApiToken: [{}] -- [{}]", tokenDto.getApiToken(), token.getApiToken());
                    if (tokenDto.getUid() == null || tokenDto.getPwd() == null || !tokenDto.getUid().equals(authorizedVo.getBrokerId()) || !tokenDto.getPwd().equals(authorizedVo.getBrokerPwd())) {
                        log.info("tokenDto: {}", tokenDto);
                        apiInvokeVo.setError(TscSsipApiErrorCode.NOTFOUND_URL.getCode());
                        resultCode = String.valueOf(TscSsipApiErrorCode.NOTFOUND_URL.getCode());
                    }
                }
                else {
                    log.info("error getApiToken: [{}] -- [{}]", tokenDto.getApiToken(), token.getApiToken());
                    apiInvokeVo.setError(TscSsipApiErrorCode.UNREGISTERED_APITOKEN.getCode());
                    resultCode = String.valueOf(TscSsipApiErrorCode.UNREGISTERED_APITOKEN.getCode());
                }
            }
            else {
                log.info("{}", token);
                apiInvokeVo.setError(TscSsipApiErrorCode.APITOKEN_EXPIRED.getCode());
                resultCode = String.valueOf(TscSsipApiErrorCode.APITOKEN_EXPIRED.getCode());
            }
        }
        catch (Exception e) {
            log.error("Exception: {}", e.getMessage());
            apiInvokeVo.setError(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
            resultCode = String.valueOf(TscSsipApiErrorCode.ERROR_INTERNAL_DATA.getCode());
        }

        result.setResult(resultCode);

        // 이력저장
        this.tscSsipApiService.insertInvokeHs(apiInvokeVo, true);
        return new ResponseEntity<>(result, HttpStatus.OK);
    }

}
