package me.chyxion.tigon.webmvc;

import java.util.List;
import java.util.Collections;
import java.nio.charset.StandardCharsets;
import org.springframework.http.MediaType;
import org.springframework.context.annotation.Bean;
import org.springframework.format.FormatterRegistry;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.http.converter.StringHttpMessageConverter;
import me.chyxion.tigon.webmvc.formatter.TrimAnnotationFormatterFactory;
import me.chyxion.tigon.webmvc.converter.StringToJSONArrayTypeConverter;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4;
import me.chyxion.tigon.webmvc.converter.StringToJSONObjectTypeConverter;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import me.chyxion.tigon.webmvc.formatter.EmptyToNullAnnotationFormatterFactory;
import org.springframework.format.number.NumberFormatAnnotationFormatterFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;

/**
 * @author Shaun Chyxion <br>
 * chyxion@163.com <br>
 * Mar 01, 2017 10:35:14
 */
@EnableWebMvc
@Configuration
@EnableAspectJAutoProxy
@ConditionalOnWebApplication
@ImportResource("classpath*:spring/spring-*.xml")
public class TigonWebConfiguration implements WebMvcConfigurer {

    /**
     * {@inheritDoc}
     */
    @Override
    public void addFormatters(final FormatterRegistry registry) {
        // converters
        registry.addConverter(new StringToJSONObjectTypeConverter());
        registry.addConverter(new StringToJSONArrayTypeConverter());

        // formatters
        registry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
        registry.addFormatterForFieldAnnotation(new EmptyToNullAnnotationFormatterFactory());
        registry.addFormatterForFieldAnnotation(new TrimAnnotationFormatterFactory());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void addReturnValueHandlers(
        final List<HandlerMethodReturnValueHandler> returnValueHandlers) {
        returnValueHandlers.add(returnValueHandler());
    }

    @Bean
    public HandlerMethodReturnValueHandler returnValueHandler() {
        return new TigonReturnValueHandler();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void configurePathMatch(final PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(false);
        configurer.setUseRegisteredSuffixPatternMatch(false);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void configureMessageConverters(
            List<HttpMessageConverter<?>> converters) {
        converters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        final FastJsonHttpMessageConverter4 fastJsonMessageConverter =
            new FastJsonHttpMessageConverter4();
        fastJsonMessageConverter.setSupportedMediaTypes(
                Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));

        fastJsonMessageConverter.getFastJsonConfig()
            .setSerializerFeatures(
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteNullListAsEmpty,
                SerializerFeature.WriteNullBooleanAsFalse);

        converters.add(fastJsonMessageConverter);
    }
}
