package uk.ac.ebi.quickgo.annotation.controller;

import uk.ac.ebi.quickgo.annotation.download.http.GAFHttpMessageConverter;
import uk.ac.ebi.quickgo.annotation.download.http.GPADHttpMessageConverter;

import java.util.List;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.slf4j.Logger;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.ResultMatcher;

import static java.util.Arrays.asList;
import static org.slf4j.LoggerFactory.getLogger;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;

/**
 * Contains logic required to verify the response of a download is correct.
 *
 * Created 30/01/17
 * @author Edd
 */
public class DownloadResponseVerifier {
    private static final Logger LOGGER = getLogger(DownloadResponseVerifier.class);

    private DownloadResponseVerifier() {}

    static ResultMatcher nonNullMandatoryFieldsExist(MediaType mediaType) {
        Matcher<String> fieldMatcher;
        if (mediaType.getSubtype().equals(GAFHttpMessageConverter.SUB_TYPE)) {
            fieldMatcher = new GAFMandatoryFieldMatcher();
        } else if (mediaType.getSubtype().equals(GPADHttpMessageConverter.SUB_TYPE)) {
            fieldMatcher = new GPADMandatoryFieldMatcher();
        } else {
            throw new IllegalArgumentException("Unknown media type: " + mediaType);
        }

        return content().string(fieldMatcher);
    }

    static class GAFMandatoryFieldMatcher extends TypeSafeMatcher<String> {
        private static final List<Integer> MANDATORY_INDICES = asList(0, 1, 2, 4, 5, 6, 8, 11, 12, 13, 14);

        @Override public void describeTo(Description description) {
            description.appendText("mandatory indices were not populated: " + MANDATORY_INDICES);
        }

        @Override protected boolean matchesSafely(String s) {
            String[] lines = s.split("\n");
            for (String line : lines) {
                if (!line.startsWith("!")) {
                    String[] components = line.split("\t");
                    if (components.length != 17) {
                        LOGGER.error("GAF line should contain 17 fields, but found: " + components.length);
                        return false;
                    }
                    for (Integer mandatoryIndex : MANDATORY_INDICES) {
                        if (components[mandatoryIndex].isEmpty()) {
                            LOGGER.error("Mandatory GAF index should not be empty: " + mandatoryIndex);
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    }

    static class GPADMandatoryFieldMatcher extends TypeSafeMatcher<String> {
        private static final List<Integer> MANDATORY_INDICES = asList(0, 1, 2, 4, 5, 8, 9);

        @Override public void describeTo(Description description) {
            description.appendText("mandatory indices were not populated: " + MANDATORY_INDICES);
        }

        @Override protected boolean matchesSafely(String s) {
            String[] lines = s.split("\n");
            for (String line : lines) {
                if (!line.startsWith("!")) {
                    String[] components = line.split("\t");
                    if (components.length != 12) {
                        LOGGER.error("GPAD line should contain 12 fields, but found: " + components.length);
                        return false;
                    }
                    for (Integer mandatoryIndex : MANDATORY_INDICES) {
                        if (components[mandatoryIndex].isEmpty()) {
                            LOGGER.error("Mandatory GPAD index should not be empty: " + mandatoryIndex);
                            return false;
                        }
                    }
                }
            }
            return true;
        }
    }
}

@@ -97,107 +97,24 @@
 ttp.
-GAFHttpMessageConverter;%0Aimport uk.ac.ebi.quickgo.annotation.download.http.GPADHttpMessageConverter
+MediaTypeFactory
 ;%0A%0Ai
@@ -662,23 +662,16 @@
 Edd%0A */%0A
-public 
 class Do
@@ -983,32 +983,29 @@
 als(
-GAFHttpMessageConverter.
+MediaTypeFactory.GAF_
 SUB_
@@ -1125,33 +1125,173 @@
 als(
-GPADHttpMessageConverter.
+MediaTypeFactory.GPAD_SUB_TYPE)) %7B%0A            fieldMatcher = new GPADMandatoryFieldMatcher();%0A        %7D else if (mediaType.getSubtype().equals(MediaTypeFactory.TSV_
 SUB_
@@ -1322,36 +1322,35 @@
 ldMatcher = new 
-GPAD
+TSV
 MandatoryFieldMa
@@ -3987,11 +3987,1416 @@
  %7D%0A    %7D
+%0A%0A    static class TSVMandatoryFieldMatcher extends TypeSafeMatcher%3CString%3E %7B%0A        private static final int FIELD_COUNT = 11;%0A        private static final String TYPE = %22TSV%22;%0A        private static final List%3CInteger%3E MANDATORY_INDICES = asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);%0A%0A        @Override public void describeTo(Description description) %7B%0A            description.appendText(%22mandatory indices were not populated: %22 + MANDATORY_INDICES);%0A        %7D%0A%0A        @Override protected boolean matchesSafely(String s) %7B%0A            String%5B%5D lines = s.split(%22%5Cn%22);%0A            for (String line : lines) %7B%0A                if (!line.startsWith(%22!%22)) %7B%0A                    String%5B%5D components = line.split(%22%5Ct%22);%0A                    if (components.length != FIELD_COUNT) %7B%0A                        LOGGER.error(TYPE + %22 line should contain %22 + FIELD_COUNT + %22 fields, but found: %22 + components%0A                                .length);%0A                        return false;%0A                    %7D%0A                    for (Integer mandatoryIndex : MANDATORY_INDICES) %7B%0A                        if (components%5BmandatoryIndex%5D.isEmpty()) %7B%0A                            LOGGER.error(%22Mandatory %22 + TYPE + %22 index should not be empty: %22 + mandatoryIndex);%0A                            return false;%0A                        %7D%0A                    %7D%0A                %7D%0A            %7D%0A            return true;%0A        %7D%0A    %7D
 %0A%7D%0A

Use MediaTypeFactory for MediaType definintions. Add TSVMandatoryFieldMatcher.