package uk.gov.register.functional;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import uk.gov.register.functional.app.RegisterRule;

import javax.ws.rs.core.Response;
import java.util.List;
import java.util.Map;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.isEmptyOrNullString;
import static uk.gov.register.functional.app.TestRegister.address;

public class VerifiableLogResourceFunctionalTest {

    @ClassRule
    public static RegisterRule register = new RegisterRule();
    private final String proofIdentifier = "merkle:sha-256";

    @Before
    public void publishTestMessages() throws Throwable {
        register.wipe();
        register.mintLines(address, "{\"address\":\"1111\",\"street\":\"elvis\"}", "{\"address\":\"2222\",\"street\":\"presley\"}", "{\"address\":\"3333\",\"street\":\"ellis\"}", "{\"address\":\"4444\",\"street\":\"pretzel\"}", "{\"address\":\"5555\",\"street\":\"elfsley\"}");
    }

    @Test
    public void getRegisterProof() {
        Response response = register.getRequest(address, "/proof/register/" + proofIdentifier);

        assertThat(response.getStatus(), equalTo(200));

        Map<?,?> responseData = response.readEntity(Map.class);
        assertThat(responseData.get("proof-identifier").toString(), equalTo(proofIdentifier));
        assertThat(responseData.get("root-hash").toString(), not(isEmptyOrNullString()));
    }

    @Test
    public void getEntryProof() {
        Response response = register.getRequest(address, "/proof/entry/1/5/" + proofIdentifier);

        assertThat(response.getStatus(), equalTo(200));

        Map<?,?> responseData = response.readEntity(Map.class);
        assertThat(responseData.get("proof-identifier").toString(), equalTo(proofIdentifier));
        assertThat(responseData.get("entry-number").toString(), equalTo("1"));

        List<?> auditPath = (List)(responseData.get("merkle-audit-path"));
        assertThat(auditPath, hasSize(3));
    }

    @Test
    public void getConsistencyProof() {
        Response response = register.getRequest(address, "/proof/consistency/2/5/" + proofIdentifier);

        assertThat(response.getStatus(), equalTo(200));

        Map<?,?> responseData = response.readEntity(Map.class);
        assertThat(responseData.get("proof-identifier").toString(), equalTo(proofIdentifier));

        List<?> auditPath = (List)(responseData.get("merkle-consistency-nodes"));
        assertThat(auditPath, hasSize(2));
    }
}

@@ -386,16 +386,63 @@
 rtThat;%0A
+import static org.hamcrest.Matchers.everyItem;%0A
 import s
@@ -478,16 +478,16 @@
 asSize;%0A
-
 import s
@@ -535,16 +535,58 @@
 String;%0A
+import static org.hamcrest.Matchers.isIn;%0A
 import s
@@ -643,16 +643,84 @@
 address;
+%0Aimport static uk.gov.register.functional.app.TestRegister.postcode;
 %0A%0Apublic
@@ -1276,16 +1276,179 @@
 y%5C%22%7D%22);%0A
+        register.mintLines(postcode, %22%7B%5C%22postcode%5C%22:%5C%22P1%5C%22%7D%22, %22%7B%5C%22postcode%5C%22:%5C%22P2%5C%22%7D%22, %22%7B%5C%22postcode%5C%22:%5C%22P3%5C%22%7D%22, %22%7B%5C%22postcode%5C%22:%5C%22P4%5C%22%7D%22, %22%7B%5C%22postcode%5C%22:%5C%22P5%5C%22%7D%22);%0A
     %7D%0A%0A 
@@ -2915,24 +2915,24 @@
 y-nodes%22));%0A
-
         asse
@@ -2967,11 +2967,893 @@
 );%0A    %7D
+%0A%0A    @SuppressWarnings(%22unchecked%22)%0A    @Test%0A    public void registerProofsForDifferentRegistersAreIndependent() %7B%0A        // This test exists to ensure that we aren't accidentally sharing the same MemoizationStore between%0A        // two different register instances.%0A        // We get a proof of the same shape from two different registers, and verify that there are no%0A        // hashes that exist in both proofs.%0A%0A        List%3CString%3E addressAuditPath = (List%3CString%3E) register.getRequest(address, %22/proof/entry/3/5/%22 + proofIdentifier)%0A                .readEntity(Map.class).get(%22merkle-audit-path%22);%0A        List%3CString%3E postcodeAuditPath = (List%3CString%3E) register.getRequest(postcode, %22/proof/entry/3/5/%22 + proofIdentifier)%0A                .readEntity(Map.class).get(%22merkle-audit-path%22);%0A%0A        assertThat(addressAuditPath, everyItem(not(isIn(postcodeAuditPath))));%0A    %7D
 %0A%7D%0A

test independence of MemoizationStores