package retromock.parser;

import org.junit.Test;
import retrofit.client.Header;
import retrofit.client.Response;
import retrofit.mime.TypedByteArray;
import retromock.test.FileLocator;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import static org.junit.Assert.*;

public class HttpParserTest {

    static final List<Path> HTTP_FILES = FileLocator.findAllInClasspath("http-*-response.txt");
    static final String LOCALHOST = "http://localhost";
    static final String NAME_VALUE = "\"\\w+?\"\\s*:\\s*\".+?\",?\\s*";
    static final String LIST = "\\[\\s*(" + NAME_VALUE +  ")+\\],?\\s*";
    static final String MULTI_LIST = "\\[\\s*(" + NAME_VALUE + "|" + LIST + ")+\\],?\\s*";
    static final Pattern JSON_PATTERN = Pattern.compile("\\{\\s*(" + NAME_VALUE + "|" + MULTI_LIST + ")+\\s*\\}");

    @Test
    public void testParse200ResponseFromFile() throws Exception {
        Response response = HttpParser.parse(LOCALHOST, getFile("http-200-response.txt"));
        assertNotNull(response);
        assertEquals(LOCALHOST, response.getUrl());
        assertEquals(200, response.getStatus());
        assertEquals("OK", response.getReason());
        Map<String, String> headers = headerMap(response.getHeaders());
        assertEquals("Flat-File", headers.get("X-Powered-By"));
        assertTrue(response.getBody() instanceof TypedByteArray);
        TypedByteArray body = (TypedByteArray) response.getBody();
        assertEquals(headers.get("Content-Type"), body.mimeType());
        assertEquals(headers.get("Content-Length"), String.valueOf(body.length()));
        String bodyAsStr = new String(body.getBytes());
        assertTrue(JSON_PATTERN.matcher(bodyAsStr.replaceAll("\n", "")).matches());
    }

    @Test
    public void testParse404ResponseFromFile() throws Exception {
        Response response = HttpParser.parse(LOCALHOST, getFile("http-404-response.txt"));
        assertNotNull(response);
        assertEquals(LOCALHOST, response.getUrl());
        assertEquals(404, response.getStatus());
        assertEquals("Not Found", response.getReason());
        Map<String, String> headers = headerMap(response.getHeaders());
        assertEquals("Flat-File", headers.get("X-Powered-By"));
        assertEquals(headers.get("Content-Length"), "0");
    }

    private Map<String, String> headerMap(List<Header> headers) {
        Map<String, String> headerMap = new HashMap<>();
        for (Header header : headers) {
            headerMap.put(header.getName(), header.getValue());
        }
        return headerMap;
    }

    private static Path getFile(String name) {
        Path fileName = Paths.get(name);
        for (Path path : HTTP_FILES) {
            if (path.endsWith(fileName)) {
                return path;
            }
        }
        return null;
    }
}

@@ -16,24 +16,53 @@
 ck.parser;%0A%0A
+import com.google.gson.Gson;%0A
 import org.j
@@ -68,24 +68,24 @@
 junit.Test;%0A
-
 import retro
@@ -207,16 +207,59 @@
 Locator;
+%0Aimport retromock.test.Http200ResponseBean;
 %0A%0Aimport
@@ -381,40 +381,8 @@
 Map;
-%0Aimport java.util.regex.Pattern;
 %0A%0Aim
@@ -618,339 +618,29 @@
 nal 
-String NAME_VALUE = %22%5C%22%5C%5Cw+?%5C%22%5C%5Cs*:%5C%5Cs*%5C%22.+?%5C%22,?%5C%5Cs*%22;%0A    static final String LIST = %22%5C%5C%5B%5C%5Cs*(%22 + NAME_VALUE +  %22)+%5C%5C%5D,?%5C%5Cs*%22;%0A    static final String MULTI_LIST = %22%5C%5C%5B%5C%5Cs*(%22 + NAME_VALUE + %22%7C%22 + LIST + %22)+%5C%5C%5D,?%5C%5Cs*%22;%0A    static final Pattern JSON_PATTERN = Pattern.compile(%22%5C%5C%7B%5C%5Cs*(%22 + NAME_VALUE + %22%7C%22 + MULTI_LIST + %22)+%5C%5Cs*%5C%5C%7D%22
+Gson GSON = new Gson(
 );%0A%0A
@@ -1423,135 +1423,214 @@
     
-String bodyAsStr = new String(body.getBytes());%0A        assertTrue(JSON_PATTERN.matcher(bodyAsStr.replaceAll(%22%5Cn%22, %22%22)).matches
+Http200ResponseBean bodyAsBean = GSON.fromJson(new String(body.getBytes()), Http200ResponseBean.class);%0A        assertEquals(%22test%22, bodyAsBean.getTitle());%0A        assertEquals(%22qwerty%22, bodyAsBean.getFoot
 ());

verify using Http200ResponseBean