package com.github.bedrin.httpbatch;

import com.github.bedrin.httpbatch.io.BoundedInputStream;
import com.github.bedrin.httpbatch.io.HeaderParser;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.Arrays;
import java.util.Map;

public class MultipartParser {

    private final String boundary;

    public MultipartParser(String boundary) {
        this.boundary = "--" + boundary;
    }

    private void drainInputStream(InputStream is) throws IOException {
        while (is.read() != -1);
    }

    private byte[] printInputStream(InputStream is) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[8192];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }
        System.out.print(new String(baos.toByteArray()));
        return baos.toByteArray();
    }

    public void parseMultipartRequest(InputStream inputStream) throws IOException {

        PushbackInputStream pis = new PushbackInputStream(inputStream);

        // preface
        {
            pis.unread('\n');
            BoundedInputStream bis = new BoundedInputStream(pis, boundary.getBytes(), BoundedInputStream.Prefix.NEW_LINE);
            System.out.print("<PREFACE>");
            printInputStream(bis);
            System.out.println("</PREFACE>");
        }

        // parts
        do {
            BoundedInputStream bis = new BoundedInputStream(pis, boundary.getBytes(), BoundedInputStream.Prefix.NEW_LINE);
            System.out.print("<PART>");
            final HeaderParser headerParser = new HeaderParser(false);
            for (Map.Entry<String, String> entry : headerParser.parseHeader(bis).entrySet()) {
                System.out.println("Header: " + entry.getKey() + ": " + entry.getValue());
            }
            if (printInputStream(bis).length == 0) break;
            System.out.println("</PART>");
        } while (true);

    }

}

@@ -1086,24 +1086,86 @@
 xception %7B%0A%0A
+        HeaderParser headerParser = new HeaderParser(false);%0A%0A
         Push
@@ -1221,16 +1221,19 @@
 utStream
+, 2
 );%0A%0A    
@@ -1286,16 +1286,50 @@
 d('%5Cn');
+ // todo workaround for no preface
 %0A       
@@ -1325,39 +1325,37 @@
 ace%0A            
-Bounded
+drain
 InputStream bis 
@@ -1341,39 +1341,33 @@
 drainInputStream
- bis = 
+(
 new BoundedInput
@@ -1426,32 +1426,33 @@
 Prefix.NEW_LINE)
+)
 ;%0A            Sy
@@ -1449,123 +1449,40 @@
     
-    System.out.print(%22%3CPREFACE%3E%22);%0A            printInputStream(bis);%0A            System.out.println(%22%3C/PREFACE%3E%22);
+%7D%0A%0A        // parts%0A        do %7B
 %0A   
@@ -1490,40 +1490,40 @@
     
-%7D%0A%0A
     
-    // parts%0A        do %7B
+if (wasLastPart(pis)) break;
 %0A   
@@ -1658,291 +1658,591 @@
     
-System.out.print(%22%3CPART%3E%22);%0A            final HeaderParser headerParser = new HeaderParser(false);%0A            for (Map.Entry%3CString, String%3E entry : headerParser.parseHeader(bis).entrySet()) %7B%0A                System.out.println(%22Header: %22 + entry.getKey() + %22: %22 + entry.getValue())
+final Map%3CString, String%3E headers = headerParser.parseHeader(bis);%0A            if (printInputStream(bis).length == 0) break;%0A        %7D while (true);%0A%0A        // epilogue%0A        drainInputStream(pis); // todo do we really need to drain it?%0A%0A    %7D%0A%0A    private boolean wasLastPart(PushbackInputStream pis) throws IOException %7B%0A        int a = pis.read();%0A        if (-1 == a) %7B%0A            return true;%0A        %7D else if ('-' == a) %7B%0A            int b = pis.read();%0A            if (-1 == b) %7B%0A                return true;%0A            %7D else if ('-' == b) %7B%0A                return true
 ;%0A  
@@ -2244,32 +2244,39 @@
 e;%0A            %7D
+ else %7B
 %0A            if 
@@ -2276,121 +2276,147 @@
     
-if (printInputStream(bis).length == 0) break;%0A            System.out.println(%22%3C/PART%3E%22);%0A        %7D while (true);%0A
+    pis.unread(a);%0A                pis.unread(b);%0A            %7D%0A        %7D else %7B%0A            pis.unread(a);%0A        %7D%0A        return false;
 %0A   

Support multipart message epilogue