package com.priusis.client.extensions.http;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.priusis.client.extensions.http.conf.HttpRequestProcessingError;
import com.priusis.client.service.MqttRpcDataMessage;
import com.priusis.client.service.TenantManagerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.priusis.client.util.JsonTools.fromString;

@RestController
@Slf4j
public class HttpController {

    @Autowired
    private TenantManagerService service;

    private ObjectMapper mapper = new ObjectMapper();

    @RequestMapping(value = "/uplink/{token}", method = RequestMethod.POST)
    public void handleRequest(@PathVariable String token, @RequestBody String body) throws Exception {
        service.processRequest(token, body);
    }

    @RequestMapping(value = "/uplink_event/{token}", method = RequestMethod.POST)
    public void handleEventRequest(@PathVariable String token, @RequestBody String body) throws Exception {
        service.processEventRequest(token, body);
    }

    @RequestMapping(value = "/rpc_cmd/{method}", method = RequestMethod.GET)
    public MqttRpcDataMessage getRpcCmdDataRequest(@PathVariable String method) throws Exception {
        MqttRpcDataMessage mqttRpcDataMessage = service.readFromFile(method);
        return mqttRpcDataMessage;
    }

    @RequestMapping(value = "/rpc_cmd", method = RequestMethod.POST)
    public void handleRpcCmdDataRequest(@RequestBody String body) {
        JsonNode payload = fromString(body);
        MqttRpcDataMessage mqttRpcDataMessage = MqttRpcDataMessage.builder().sendTime(payload.get("sendTime").asLong())
                .method(payload.get("method").asText()).params(payload.get("params").toPrettyString()).build();
        // 存储rpc下发的数据
        try {
            service.flushRpcDataToFile(mqttRpcDataMessage);
        } catch (IOException e) {
            log.error("Failed to process rpc command persistent : {}", body);
        }
    }

    @ExceptionHandler(Exception.class)
    public void handlePriusisiotException(Exception exception, HttpServletResponse response) {
        log.debug("Processing exception {}", exception.getMessage(), exception);
        if (!response.isCommitted()) {
            try {
                response.setContentType(MediaType.APPLICATION_JSON_VALUE);
                if (exception instanceof SecurityException) {
                    response.setStatus(HttpStatus.FORBIDDEN.value());
                    mapper.writeValue(response.getWriter(),
                            new HttpRequestProcessingError("You don't have permission to perform this operation!"));
                } else {
                    response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
                    mapper.writeValue(response.getWriter(), new HttpRequestProcessingError(exception.getMessage()));
                }
            } catch (IOException e) {
                log.error("Can't handle exception", e);
            }
        }
    }

}
