package org.iri_research.renkan.test.rest;

import java.io.IOException;

import org.iri_research.renkan.models.Edge;
import org.iri_research.renkan.models.Node;
import org.iri_research.renkan.models.Project;
import org.iri_research.renkan.rest.ObjectMapperProvider;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("models-context.xml")
public class DeserializationTest {

    private Logger logger = LoggerFactory.getLogger(DeserializationTest.class);
    
    @Autowired
    private ObjectMapperProvider objectMapperProvider;
    
    private String testJSON = "{\n" + 
            "  \"users\": [],\n" + 
            "  \"nodes\": [\n" + 
            "    {\n" + 
            "      \"title\": \"node0\",\n" + 
            "      \"uri\": \"\",\n" + 
            "      \"description\": \"This is node 0\",\n" + 
            "      \"position\": {\n" + 
            "        \"x\": -90.5,\n" + 
            "        \"y\": 235\n" + 
            "      },\n" + 
            "      \"image\": null,\n" + 
            "      \"style\": {\"color\": \"#ffffff\"},\n" + 
            "      \"created_by\": null,\n" + 
            "      \"size\": 0,\n" + 
            "      \"@id\": \"224d9578-d2a2-4d7d-ae04-9a674a0ecd08\"\n" + 
            "    },\n" + 
            "    {\n" + 
            "      \"title\": \"node1\",\n" + 
            "      \"uri\": \"\",\n" + 
            "      \"description\": \"This is node 1\",\n" + 
            "      \"position\": {\n" + 
            "        \"x\": -429.5984204131227,\n" + 
            "        \"y\": 98.65856622114218\n" + 
            "      },\n" + 
            "      \"image\": null,\n" + 
            "      \"style\": {\"color\": \"#ffffff\"},\n" + 
            "      \"created_by\": null,\n" + 
            "      \"size\": 0,\n" + 
            "      \"@id\": \"1b73ea10-e557-443e-b73d-dc00fb63d60c\"\n" + 
            "    },\n" + 
            "    {\n" + 
            "      \"title\": \"node2\",\n" + 
            "      \"uri\": \"\",\n" + 
            "      \"description\": \"This is node 2\",\n" + 
            "      \"position\": {\n" + 
            "        \"x\": -496.5,\n" + 
            "        \"y\": -86\n" + 
            "      },\n" + 
            "      \"image\": null,\n" + 
            "      \"style\": {\"color\": \"#ffffff\"},\n" + 
            "      \"created_by\": null,\n" + 
            "      \"size\": 0,\n" + 
            "      \"@id\": \"af5e97b0-2692-4dd2-8726-75a02cf40dff\"\n" + 
            "    }\n" + 
            "  ],\n" + 
            "  \"edges\": [\n" + 
            "    {\n" + 
            "      \"title\": \"edge0\",\n" + 
            "      \"uri\": \"\",\n" + 
            "      \"description\": \"This is edge 0\",\n" + 
            "      \"from\": \"af5e97b0-2692-4dd2-8726-75a02cf40dff\",\n" + 
            "      \"to\": \"1b73ea10-e557-443e-b73d-dc00fb63d60c\",\n" + 
            "      \"style\": {\"color\": \"#ffffff\"},\n" + 
            "      \"created_by\": null\n" + 
            "    }\n" + 
            "  ],\n" + 
            "  \"title\": \"Test Deserialization\",\n" + 
            "  \"description\": \"Description test deserialization.\",\n" + 
            "  \"uri\": null,\n" + 
            "  \"color\": \"#ffff01\",\n" + 
            "  \"revCounter\": 94,\n" + 
            "  \"created\": 1385377361448,\n" + 
            "  \"updated\": 1400568565070\n" + 
            "}";
    
    @Before
    public void setup() {
        logger.debug("Setup");
    }

    @Test
    public void testDeserialization() throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = this.objectMapperProvider.getContext(ObjectMapper.class);
        
        Project p = mapper.readValue(testJSON, Project.class);

        Assert.assertNotNull(p);
        Assert.assertEquals("Title must be the same", "Test Deserialization", p.getTitle());
        Assert.assertEquals("Description must be the same", "Description test deserialization.", p.getDescription());
        
        Assert.assertEquals("Must have 3 nodes", 3, p.getNodes().size());
        Assert.assertEquals("Must have 1 edge", 1, p.getEdges().size());

        Assert.assertEquals("Edge goes from node node2", "node2", p.getEdges().get(0).getFromNode().getTitle() );
        Assert.assertEquals("Edge goes to node node1", "node1", p.getEdges().get(0).getToNode().getTitle() );
    }
    
    @Test
    public void testDeserializationColor() throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = this.objectMapperProvider.getContext(ObjectMapper.class);
        
        Project p = mapper.readValue(testJSON, Project.class);

        Assert.assertNotNull(p);
        
        Assert.assertEquals("Color of node is #ffffff", "#ffffff", p.getNodes().get(0).getStyle().getColor());
    }
    
    @Test
    public void testDeserializationId() throws JsonParseException, JsonMappingException, IOException {

        ObjectMapper mapper = this.objectMapperProvider.getContext(ObjectMapper.class);
        
        Project p = mapper.readValue(testJSON, Project.class);

        Assert.assertNotNull("Project is null",p);
        Assert.assertNotNull("Project Id is null", p.getId());

        for (Node n : p.getNodes()) {
            Assert.assertNotNull("Id of node must not be null", n.getId());
        }
        for (Edge e : p.getEdges()) {
            Assert.assertNotNull("Id of edge must not be null", e.getId());
        }
    }
    
    @After
    public void teardown() {
    }
}
