package com.jscape.inet.http.protocol.marshaling;

import com.jscape.inet.http.protocol.messages.Header;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Alex Usun
 */
public class HeadersCodec {

    public static Header[] readValue(InputStream in)
            throws IOException {
        List<HeaderBuilder> builders = new LinkedList<>();
        String line;
        HeaderBuilder currentHeader = null;
        while ((line = LineCodec.readStringCRLF(StandardCharsets.US_ASCII, in)) != null && line.length() > 0) {
            if (currentHeader != null && (line.startsWith(" ") || line.startsWith("\t"))) {
                currentHeader.value.append(line.trim());
            } else {
                int valueIndex = line.indexOf(':');
                String name = line.substring(0, valueIndex).trim();
                String value = line.substring(valueIndex + 1).trim();
                currentHeader = new HeaderBuilder(name, value);
                builders.add(currentHeader);
            }
        }
        
        Header[] headers = new Header[builders.size()];
        int i = 0;
        for (HeaderBuilder builder : builders) {
            headers[i++] = builder.build();
        }

        return headers;
    }

    public static void writeValue(Header[] value, OutputStream out)
            throws IOException {
        for (Header header : value) {
            String data = String.format("%s: %s", header.name, header.value);
            LineCodec.writeStringCRLF(data, StandardCharsets.US_ASCII, out);
        }

        LineCodec.writeCRLF(out);
    }

    private HeadersCodec() {
        // empty
    }
    
    private static class HeaderBuilder {
        
        public final String name;
        public final StringBuilder value;
    
        private HeaderBuilder(String name, String value) {
            this.name = name;
            this.value = new StringBuilder(value);
        }
        
        public Header build() {
            return new Header(this.name, this.value.toString());
        }
    }
}
