package uk.gov.register.functional;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.ImmutableMap;
import io.dropwizard.testing.ConfigOverride;
import io.dropwizard.testing.ResourceHelpers;
import io.dropwizard.testing.junit.DropwizardAppRule;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import uk.gov.register.RegisterApplication;
import uk.gov.register.RegisterConfiguration;
import uk.gov.register.core.Entry;
import uk.gov.register.core.Item;
import uk.gov.register.functional.app.CleanDatabaseRule;
import uk.gov.register.functional.db.TestDBItem;
import uk.gov.register.functional.db.TestRecord;
import uk.gov.register.util.CanonicalJsonMapper;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.List;
import java.util.Map;

import static org.hamcrest.Matchers.contains;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static uk.gov.register.functional.db.TestDBSupport.*;

public class LoadSerializedFunctionalTest {
    public static final int APPLICATION_PORT = 9000;
    public static final MediaType RSF_TYPE = new MediaType("application", "uk-gov-rsf", "UTF-8");

    private final DropwizardAppRule<RegisterConfiguration> appRule = new DropwizardAppRule<>(RegisterApplication.class,
            ResourceHelpers.resourceFilePath("test-app-config.yaml"),
            ConfigOverride.config("database.url", postgresConnectionString),
            ConfigOverride.config("jerseyClient.timeout", "3000ms"),
            ConfigOverride.config("register", "register"));

    @Rule
    public TestRule ruleChain = RuleChain.
            outerRule(new CleanDatabaseRule()).
            around(appRule);


    private final CanonicalJsonMapper canonicalJsonMapper = new CanonicalJsonMapper();


    @Test
    public void checkMessageIsConsumedAndStoredInDatabase() throws Exception {
        String input = new String(Files.readAllBytes(Paths.get("src/test/resources/fixtures/serialized", "register-register-rsf.tsv")));
        Response r = send(input);
        assertThat(r.getStatus(), equalTo(204));

        TestDBItem storedItem = testItemDAO.getItems().get(0);
        assertThat(storedItem.contents.toString(), equalTo("{\"text\":\"SomeText\",\"register\":\"ft_openregister_test\"}"));
        assertThat(storedItem.sha256hex, equalTo("3cee6dfc567f2157208edc4a0ef9c1b417302bad69ee06b3e96f80988b37f254"));

        Entry entry = testEntryDAO.getAllEntries().get(0);
        assertThat(entry.getEntryNumber(), is(0));
        assertThat(entry.getSha256hex(), is("3cee6dfc567f2157208edc4a0ef9c1b417302bad69ee06b3e96f80988b37f254"));

        TestRecord record = testRecordDAO.getRecord("ft_openregister_test");
        assertThat(record.getEntryNumber(), equalTo(0));
        assertThat(record.getPrimaryKey(), equalTo("ft_openregister_test"));


    }

    @Test
    public void shouldReturnBadRequestWhenNotValidRsf() {
        String entry = "foo bar";
        Response response = send(entry);
        assertThat(response.getStatus(), equalTo(400));
        assertThat(response.readEntity(String.class), equalTo("Error parsing : line must begin with legal command not: foo bar"));
    }

    private Response send(String payload) {
        return authenticatingClient().target("http://localhost:" + APPLICATION_PORT + "/load-rsf")
                .request(RSF_TYPE)
                .post(Entity.entity(payload, RSF_TYPE));

    }

    private JerseyClient authenticatingClient() {
        ClientConfig configuration = new ClientConfig();
        configuration.register(HttpAuthenticationFeature.basic("foo", "bar"));
        return JerseyClientBuilder.createClient(configuration);
    }

    private Client testClient() {
        return new io.dropwizard.client.JerseyClientBuilder(appRule.getEnvironment())
                .using(appRule.getConfiguration().getJerseyClientConfiguration())
                .build("test client");
    }
}

@@ -34,103 +34,8 @@
 l;%0A%0A
-import com.fasterxml.jackson.databind.JsonNode;%0Aimport com.google.common.collect.ImmutableMap;%0A
 impo
@@ -648,42 +648,8 @@
 ry;%0A
-import uk.gov.register.core.Item;%0A
 impo
@@ -847,16 +847,77 @@
 nMapper;
+%0Aimport uk.gov.register.views.representations.ExtraMediaType;
 %0A%0Aimport
@@ -1107,125 +1107,8 @@
 hs;%0A
-import java.time.Instant;%0Aimport java.util.List;%0Aimport java.util.Map;%0A%0Aimport static org.hamcrest.Matchers.contains;
 %0Aimp
@@ -1397,106 +1397,8 @@
 000;
-%0A    public static final MediaType RSF_TYPE = new MediaType(%22application%22, %22uk-gov-rsf%22, %22UTF-8%22);
 %0A%0A  
@@ -3582,16 +3582,43 @@
 request(
+ExtraMediaType.APPLICATION_
 RSF_TYPE
@@ -3664,16 +3664,43 @@
 ayload, 
+ExtraMediaType.APPLICATION_
 RSF_TYPE

Use defined ExtraMediaTypes in tests