package org.iri_research.renkan.rest;

import java.io.IOException;

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.springframework.data.mongodb.core.geo.Point;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.joda.JodaModule;

@Component
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper> {

    public static class RenkanPointDeserializer extends StdDeserializer<Point> {

        private static final long serialVersionUID = -2380557631785838410L;

        protected RenkanPointDeserializer(Class<?> vc) {
            super(vc);
        }

        @Override
        public Point deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException, JsonProcessingException {
            JsonNode node = jp.getCodec().readTree(jp);
            double x = node.get("x") != null? node.get("x").asDouble(): Double.NaN;
            double y = node.get("y") != null? node.get("y").asDouble(): Double.NaN;
            Point p = new Point(x, y);
            return p;
        }
    }
    @Override
    public ObjectMapper getContext(Class<?> type) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,
                false);
        objectMapper.registerModule(new JodaModule());
        
        SimpleModule pointModule = new SimpleModule("RenkanPointModule")
            .addDeserializer(Point.class, new RenkanPointDeserializer(Point.class));
        objectMapper.registerModule(pointModule);

        return objectMapper;
    }

}
