package uk.gov.register.views.representations.turtle;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import org.junit.Test;
import uk.gov.register.core.*;
import uk.gov.register.util.HashValue;
import uk.gov.register.views.ItemView;

import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Map;
import java.util.Set;

import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;

public class TurtleRepresentationWriterTest {
    private final RegisterResolver registerResolver = register -> URI.create("http://" + register + ".test.register.gov.uk");

    private final Set<Field> fields = ImmutableSet.of(
            new Field("address", "datatype", new RegisterName("register"), Cardinality.ONE, "text"),
            new Field("location", "datatype", new RegisterName("register"), Cardinality.ONE, "text"),
            new Field("link-values", "datatype", new RegisterName("register"), Cardinality.ONE, "text"),
            new Field("string-values", "datatype", new RegisterName("register"), Cardinality.ONE, "text"));

    @Test
    public void rendersFieldPrefixFromConfiguration() throws Exception {
        Map<String, FieldValue> map = ImmutableMap.of(
                "key1", new StringValue("value1"),
                "key2", new StringValue("value2"),
                "key3", new StringValue("val\"ue3"),
                "key4", new StringValue("value4")
        );
        ItemView itemView = new ItemView(new HashValue(HashingAlgorithm.SHA256, "hash"), map, fields);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        ItemTurtleWriter writer = new ItemTurtleWriter(() -> new RegisterName("address"), registerResolver);
        writer.writeTo(itemView, itemView.getClass(), null, null, null, null, outputStream);
        byte[] bytes = outputStream.toByteArray();
        String generatedTtl = new String(bytes, StandardCharsets.UTF_8);
        assertThat(generatedTtl, containsString("@prefix field:   <http://field.test.register.gov.uk/record/> ."));
    }

    @Test
    public void rendersEntryIdentifierFromRequestContext() throws Exception {
        Entry entry = new Entry(52, new HashValue(HashingAlgorithm.SHA256, "hash"), Instant.now(), "key", EntryType.user);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        EntryTurtleWriter writer = new EntryTurtleWriter(() -> new RegisterName("address"), registerResolver);
        writer.writeTo(entry, entry.getClass(), null, null, null, null, outputStream);
        byte[] bytes = outputStream.toByteArray();
        String generatedTtl = new String(bytes, StandardCharsets.UTF_8);
        assertThat(generatedTtl, containsString("<http://address.test.register.gov.uk/entry/52>"));
    }

    @Test
    public void rendersLinksCorrectlyAsUrls() throws Exception {
        Map<String, FieldValue> map =
                ImmutableMap.of(
                        "address", new RegisterLinkValue(new RegisterName("address"), "1111111"),
                        "location", new RegisterLinkValue(new RegisterName("address"), "location-value"),
                        "name", new StringValue("foo")
                );

        ItemView itemView = new ItemView(new HashValue(HashingAlgorithm.SHA256, "itemhash"), map, fields);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        ItemTurtleWriter writer = new ItemTurtleWriter(() -> new RegisterName("address"), registerResolver);
        writer.writeTo(itemView, itemView.getClass(), null, null, null, null, outputStream);
        byte[] bytes = outputStream.toByteArray();
        String generatedTtl = new String(bytes, StandardCharsets.UTF_8);
        assertThat(generatedTtl, containsString("field:address <http://address.test.register.gov.uk/record/1111111>"));
        assertThat(generatedTtl, containsString("field:location <http://address.test.register.gov.uk/record/location-value>"));
        assertThat(generatedTtl, containsString("field:name \"foo\""));
        assertThat(generatedTtl, containsString("<http://address.test.register.gov.uk/item/sha-256:itemhash>"));
    }

    @Test
    public void rendersLists() throws Exception {
        Map<String, FieldValue> map =
                ImmutableMap.of(
                        "link-values", new ListValue(asList(new RegisterLinkValue(new RegisterName("address"), "1111111"), new RegisterLinkValue(new RegisterName("address"), "2222222"))),
                        "string-values", new ListValue(asList(new StringValue("value1"), new StringValue("value2"))),
                        "name", new StringValue("foo")
                );

        ItemView itemView = new ItemView(new HashValue(HashingAlgorithm.SHA256, "hash"), map, fields);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        ItemTurtleWriter writer = new ItemTurtleWriter(() -> new RegisterName("address"), registerResolver);
        writer.writeTo(itemView, itemView.getClass(), null, null, null, null, outputStream);

        byte[] bytes = outputStream.toByteArray();
        String generatedTtl = new String(bytes, StandardCharsets.UTF_8);

        assertThat(generatedTtl, containsString("field:link-values <http://address.test.register.gov.uk/record/1111111> , <http://address.test.register.gov.uk/record/2222222>"));
        assertThat(generatedTtl, containsString("field:string-values \"value2\" , \"value1\""));
        assertThat(generatedTtl, containsString("field:name \"foo\""));
    }
}

@@ -313,16 +313,44 @@
 Stream;%0A
+import java.io.IOException;%0A
 import j
@@ -1249,32 +1249,133 @@
 Cardinality.ONE,
+ %22text%22),%0A            new Field(%22website%22, %22datatype%22, new RegisterName(%22register%22), Cardinality.ONE,
  %22text%22));%0A%0A    
@@ -5814,11 +5814,922 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void rendersUrlValuesAsResources() throws IOException %7B%0A        Map%3CString, FieldValue%3E map =%0A                ImmutableMap.of(%0A                        %22name%22, new StringValue(%22foo%22),%0A                        %22website%22, new UrlValue(%22https://www.gov.uk%22)%0A                );%0A%0A        ItemView itemView = new ItemView(new HashValue(HashingAlgorithm.SHA256, %22hash%22), map, fields);%0A%0A        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();%0A%0A        ItemTurtleWriter writer = new ItemTurtleWriter(() -%3E new RegisterName(%22government-organisation%22), registerResolver);%0A        writer.writeTo(itemView, itemView.getClass(), null, null, null, null, outputStream);%0A%0A        byte%5B%5D bytes = outputStream.toByteArray();%0A        String generatedTtl = new String(bytes, StandardCharsets.UTF_8);%0A        assertThat(generatedTtl, containsString(%22field:website %3Chttps://www.gov.uk%3E%22));%0A    %7D
 %0A%7D%0A

Add test to validate URLs are rendered in TTL as resources rather than properties