package com.konkerlabs.platform.registry.integration.endpoints;

import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.konkerlabs.platform.registry.business.exceptions.BusinessException;
import com.konkerlabs.platform.registry.business.services.api.DeviceRegisterService;
import com.konkerlabs.platform.registry.integration.gateways.HttpGateway;
import com.konkerlabs.platform.registry.integration.processors.DeviceEventProcessor;
import com.konkerlabs.platform.utilities.parsers.json.JsonParsingService;

import lombok.Builder;
import lombok.Data;

@RestController
public class GatewayEventRestEndpoint {

    public enum Messages {
        INVALID_REQUEST_BODY("integration.rest.invalid.body"),
        INVALID_RESOURCE("integration.rest.invalid.resource"),
        INVALID_WAITTIME("integration.rest.invalid.waitTime"),
        INVALID_CHANNEL_PATTERN("integration.rest.invalid.channel"),
    	DEVICE_NOT_FOUND("integration.event_processor.channel.not_found"),
    	INVALID_REQUEST_ORIGIN("integration.rest.invalid_requrest_origin");

        private String code;

        public String getCode() {
            return code;
        }

        Messages(String code) {
            this.code = code;
        }
    }

    private ApplicationContext applicationContext;
    private DeviceEventProcessor deviceEventProcessor;
    private JsonParsingService jsonParsingService;
    private DeviceRegisterService deviceRegisterService;

    @Autowired
    public GatewayEventRestEndpoint(ApplicationContext applicationContext,
                                   DeviceEventProcessor deviceEventProcessor,
                                   JsonParsingService jsonParsingService,
                                   DeviceRegisterService deviceRegisterService) {
        this.applicationContext = applicationContext;
        this.deviceEventProcessor = deviceEventProcessor;
        this.jsonParsingService = jsonParsingService;
        this.deviceRegisterService = deviceRegisterService;
    }

    private EventResponse buildResponse(String message, Locale locale) {
        return EventResponse.builder()
                .code(message)
                .message(applicationContext.getMessage(message,null, locale)).build();
    }

    @RequestMapping(value = "gateway/pub", method = RequestMethod.POST)
    public ResponseEntity<EventResponse> onEvent(HttpServletRequest servletRequest,
    											 OAuth2Authentication oAuth2Authentication,
                                                 @RequestBody String body,
                                                 Locale locale) {
        if (!jsonParsingService.isValid(body))
            return new ResponseEntity<EventResponse>(buildResponse(Messages.INVALID_REQUEST_BODY.getCode(),locale), HttpStatus.BAD_REQUEST);

		if (servletRequest.getHeader(HttpGateway.KONKER_VERSION_HEADER) != null)
			return new ResponseEntity<EventResponse>(buildResponse(Messages.INVALID_REQUEST_ORIGIN.getCode(), locale), HttpStatus.FORBIDDEN);

        try {
        	List<Map<String, Object>> map = jsonParsingService.toListMap(body);
        	
            deviceEventProcessor.process(
            		map.get(0).get("deviceId").toString(), 
            		map.get(0).get("channel").toString(), 
            		map.get(0).get("payload").toString());
        } catch (BusinessException | JsonProcessingException e) {
            return new ResponseEntity<EventResponse>(buildResponse(e.getMessage(),locale),HttpStatus.BAD_REQUEST);
        }

        return new ResponseEntity<EventResponse>(
        		EventResponse.builder().code(String.valueOf(HttpStatus.OK.value()))
        		.message(HttpStatus.OK.name()).build(),
        		HttpStatus.OK);
    }

    @Data
    @Builder
    static class EventResponse {
        private String code;
        private String message;
    }
}

@@ -69,119 +69,500 @@
 ort 
-java.util.List;%0Aimport java.util.Locale;%0Aimport java.util.Map;%0A%0Aimport javax.servlet.http.HttpServletRequest
+com.fasterxml.jackson.core.JsonProcessingException;%0Aimport com.konkerlabs.platform.registry.business.exceptions.BusinessException;%0Aimport com.konkerlabs.platform.registry.business.services.api.DeviceRegisterService;%0Aimport com.konkerlabs.platform.registry.integration.gateways.HttpGateway;%0Aimport com.konkerlabs.platform.registry.integration.processors.DeviceEventProcessor;%0Aimport com.konkerlabs.platform.utilities.parsers.json.JsonParsingService;%0Aimport lombok.Builder;%0Aimport lombok.Data
 ;%0A
-%0A
 impo
@@ -1101,499 +1101,115 @@
 ort 
-com.fasterxml.jackson.core.JsonProcessingException;%0Aimport com.konkerlabs.platform.registry.business.exceptions.BusinessException;%0Aimport com.konkerlabs.platform.registry.business.services.api.DeviceRegisterService;%0Aimport com.konkerlabs.platform.registry.integration.gateways.HttpGateway;%0Aimport com.konkerlabs.platform.registry.integration.processors.DeviceEventProcessor;%0Aimport com.konkerlabs.platform.utilities.parsers.json.JsonParsingServic
+javax.servlet.http.HttpServletRequest;%0Aimport java.util.List;%0Aimport java.util.Local
 e;%0A
-%0A
 import 
-lombok.Builder;%0Aimport lombok.Data
+java.util.Map
 ;%0A%0A@
@@ -1545,24 +1545,24 @@
 .channel%22),%0A
-
     %09DEVICE_
@@ -1617,24 +1617,114 @@
 ot_found%22),%0A
+        INVALID_GATEWAY_LOCATION(%22integration.event_processor.gateway.location.invalid%22),%0A
     %09INVALID

add Gateway location validation