package it.enea.cruise.controller;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;

import java.util.Map;

import it.enea.cruise.exceptions.TokenNotValidException;
import org.apache.commons.io.IOUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJacksonInputMessage;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import com.google.common.net.HttpHeaders;

import org.springframework.boot.json.JsonParser;
import org.springframework.boot.json.JsonParserFactory;

import it.enea.cruise.data.InputParameters;

@ControllerAdvice
public class CustomRequestBodyAdvice implements RequestBodyAdvice {

	String input = "";
	
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {        
    	return true;
//        return methodParameter.getContainingClass() == QuestionController.class && targetType.getTypeName() == Question.class.getTypeName();
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
                                           Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
        InputStream body = inputMessage.getBody();
        input = IOUtils.toString(body, Charset.forName("UTF-8"));
      
        HttpInputMessage ret = new MappingJacksonInputMessage(new ByteArrayInputStream(input.getBytes()), inputMessage.getHeaders());
        return ret;
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
                                Class<? extends HttpMessageConverter<?>> converterType) {
        if (body instanceof InputParameters) {
        	JsonParser jsonParser = JsonParserFactory.getJsonParser();
            Map<String, Object> otherParameters = jsonParser.parseMap(input);
        	((InputParameters) body).setParameters(otherParameters);
        	((InputParameters) body).setToken(inputMessage.getHeaders().getFirst(HttpHeaders.AUTHORIZATION));
        	((InputParameters) body).setLanguage(inputMessage.getHeaders().getFirst(HttpHeaders.CONTENT_LANGUAGE));
        }
        return body;
    }

    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
                                  Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }
}