/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.products.ov.mixnet.webapp.mvc;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.Collections;

import org.junit.Test;

import com.scytl.products.ov.utils.ConfigObjectMapper;

public class MixDecValResultTest {

    private static final String FAILURE_JSON = "{\"error\":\"whatever\"}";

    private static final String SUCCESS_JSON =
        "{\"mixingDirectories\":[\"file:///\",\"file:///b/c/d/\"],\"error\":null}";

    private static final String SUCCESS_JSON_LOCAL_PATH = "{\"mixingDirectories\":[\"file:///\",\".\"],\"error\":null}";

    private static final ConfigObjectMapper objectMapper = new ConfigObjectMapper();

    @Test
    public void deserializeSuccessJson() throws IOException {
        MixDecValResult mixDecValResult = objectMapper.fromJSONToJava(SUCCESS_JSON, MixDecValResult.class);

        assertEquals(2, mixDecValResult.getMixingDirectories().size());
        assertNull(mixDecValResult.getError());
    }

    @Test
    public void deserializeFailureJson() throws IOException {
        MixDecValResult mixDecValResult = objectMapper.fromJSONToJava(FAILURE_JSON, MixDecValResult.class);

        assertEquals(Collections.emptyList(), mixDecValResult.getMixingDirectories());
        assertNotNull(mixDecValResult.getError());
    }

    @Test
    public void testErrorConstructor() throws Exception {
        MixDecValResult mixDecValResult = new MixDecValResult(new RuntimeException("That did not go well"));
        String json = objectMapper.fromJavaToJSON(mixDecValResult);

        assertThat(json, startsWith(
            "{\"mixingDirectories\":[],\"error\":{\"cause\":null,\"stackTrace\":[{\"methodName\":\"testErrorConstructor\",\"fileName\":\"MixDecValResultTest.java\","));
    }

    @Test
    public void testSuccessConstructor() throws Exception {
        MixDecValResult mixDecValResult = new MixDecValResult(Collections.singletonList(Paths.get("/")));
        String expectedJson = "{\"mixingDirectories\":[\"file:///\"],\"error\":null}";
        MixDecValResult expected = objectMapper.fromJSONToJava(expectedJson, MixDecValResult.class);

        assertEquals(objectMapper.fromJavaToJSON(expected.getMixingDirectories()),
            objectMapper.fromJavaToJSON(mixDecValResult.getMixingDirectories()));
    }

    @Test
    public void testConstructorWithLocalPaths() throws Exception {
        MixDecValResult mixDecValResult = objectMapper.fromJSONToJava(SUCCESS_JSON_LOCAL_PATH, MixDecValResult.class);

        // The first file:/// URI should be interpreted as a local path.
        assertEquals(Paths.get("/").toString(), mixDecValResult.getMixingDirectories().get(0).toString());
        // The second URI should be interpreted as the current path.
        assertEquals(Paths.get(".").toString(), mixDecValResult.getMixingDirectories().get(1).toString());
    }

    @Test
    public void testSerializationRoundtrip() throws Exception {
        MixDecValResult mixDecValResult = new MixDecValResult(Collections.singletonList(Paths.get("/")));
        String json = objectMapper.fromJavaToJSON(mixDecValResult);
        MixDecValResult newMixDecValResult = objectMapper.fromJSONToJava(json, MixDecValResult.class);

        assertTrue(mixDecValResult.getMixingDirectories().get(0).toAbsolutePath()
            .equals(newMixDecValResult.getMixingDirectories().get(0).toAbsolutePath()));
    }
}
