package kr.gmtc.gw.dev.asderecv.asde.controller;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

import javax.annotation.Resource;

import kr.gmtc.gw.dev.asderecv.asde.rest.vo.AsdeServiceVO;
import kr.gmtc.gw.dev.asderecv.asde.rest.vo.ServiceAsdeData;
import kr.gmtc.gw.dev.asderecv.asde.rest.vo.ServiceHeader;
import kr.gmtc.gw.dev.asderecv.config.ServiceConfig;
import kr.gmtc.gw.dev.asderecv.controller.MainController;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.util.concurrent.RateLimiter;


@RestController
public class AsdeServiceController{

	// 프레임 워크 구성요소 //
	/** 서비스 설정, {@code application.yml} */
	@Resource(name = "ServiceConfig")
	private ServiceConfig serviceConfig;
	
	/* 실생상태 확인 */
	private boolean running = false;
	
	/* UDP test 소켓 */
	//UDPEchoClient UDPSocket ;
	
	@Resource(name = "sendQueue")
	HashMap<Integer, Queue<ServiceAsdeData>> sendQueue;

	Queue<ServiceAsdeData> testMap = new LinkedBlockingQueue<ServiceAsdeData>();

	/* 서비스중인지 확인 */
	@Resource(name = "serviceRunnig")

	private boolean serviceRunnig = false;
	
	@Value("${asde.service.queueCount}")
	private Integer scvQcount;

	@Value("${asde.service.serviceCount}")
	private Integer scvDatacount;

	private AsdeServiceVO asdeServiceVO;

	private static RateLimiter rateLimiter;

	protected Logger logger;

	protected ObjectMapper mapper;


	public AsdeServiceController() {

		logger = LoggerFactory.getLogger(this.getClass());
		mapper = new ObjectMapper();

		// 0.33.. 초에 한 번만 호출 가능
		rateLimiter = RateLimiter.create(3);
 
  	}
	
	@GetMapping(value = "/getASDE/{qid}")
	public ResponseEntity<String> getASDE( @PathVariable Integer qid) {

		int qidx = qid -1;

		String sRetJsonData = "";

		if(!serviceRunnig) {
		}

		// if (rateLimiter.tryAcquire()) {

		// 	sRetJsonData = makeServiceData(qidx, sendQueue.get(qidx));

		// 	logger.debug("make json data END.");
		// 	return ResponseEntity.ok(sRetJsonData);
		// }else{
		// 	sRetJsonData = "처리중 요청함";
		// }

		sRetJsonData = makeServiceData(qidx, sendQueue.get(qidx));

		// logger.debug("make json data END.");
		return ResponseEntity.ok(sRetJsonData);

		// 호출할 수 없다면 429 리턴
    //	return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).build();

		// return ResponseEntity.ok(sRetJsonData);
		
	}


	private String makeServiceData(int queIdx, Queue<ServiceAsdeData> procQue){

		serviceRunnig = true;

		String sendCode, sendMsg ;
		ServiceHeader jsonHeader = new ServiceHeader();
		List<ServiceAsdeData> jsonData = new ArrayList<ServiceAsdeData>();
		
		sendCode = "200";
		sendMsg = "";
		
		asdeServiceVO = new AsdeServiceVO();
		
		int qSize = procQue.size();

		//if(qSize > 0) serviceRunnig = true ;

		if(qSize > scvDatacount) qSize = scvDatacount;

		if(queIdx > scvQcount -1 || queIdx < 0) {
			sendCode = "Err-01";
			sendMsg = "할당되지 않은 큐를 지정했습니다.";
			logger.error(sendMsg);
		}else {
			//if(procQue.peek() == null) {
			if(procQue.size() <= 0) {
				sendCode = "200";
				sendMsg = "전송할 데이터 없음.";
				// logger.error("procQue size" + " / " + procQue.size());
			}else{

				while (qSize > 0 ) {
					jsonData.add(procQue.poll());
					qSize--;
				}
			}
			
		}
		
		jsonHeader.setResult_code(sendCode);
		jsonHeader.setResult_msg(sendMsg);
		
		asdeServiceVO.setHeader(jsonHeader);
		
		if (sendCode.equals("200")) {
			
			//logger.debug("jsonData : " + jsonData.size() + " / " + jsonData);
			asdeServiceVO.setData(jsonData);

			if(jsonData.size() > 0){
				logger.debug("jsonData : " + jsonData.size()); 
			}
			// 	asdeServiceVO.setData(jsonData);
			// }else{
			// 	logger.debug("////////////////////////////////////////////////////////////////////////////////////////////////jsonData : " + jsonData.size());
			// 	asdeServiceVO.setData(new ArrayList<>());
			// 	//jsonData.add("jsonData : " + jsonData.size());
			// }
				

			
		}
		
		String sRetJsonData = "";
		try {
			sRetJsonData = mapper.writeValueAsString(asdeServiceVO);
		} catch (JsonProcessingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		serviceRunnig = false ;
		
		// if( !sendMsg.equals("")){
		// 	logger.debug("debug :" + sRetJsonData);
		// }

		return sRetJsonData;

	}




}


