/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/

package org.ofbiz.base.util;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;

import javolution.util.FastMap;

/**
 * HttpRequestFileUpload - Receive a file upload through an HttpServletRequest
 *
 */
public class HttpRequestFileUpload {

    private int BUFFER_SIZE = 4096;
    private int WAIT_INTERVAL = 200; // in milliseconds
    private int MAX_WAITS = 20;
    private int waitCount = 0;
    private String savePath;
    private String filepath;
    private String filename;
    private String contentType;
    private String overrideFilename = null;
    private Map<String, String> fields;

    public String getOverrideFilename() {
        return overrideFilename;
    }

    public void setOverrideFilename(String ofName) {
        overrideFilename = ofName;
    }

    public String getFilename() {
        return filename;
    }

    public String getFilepath() {
        return filepath;
    }

    public void setSavePath(String savePath) {
        this.savePath = savePath;
    }

    public String getContentType() {
        return contentType;
    }

    public String getFieldValue(String fieldName) {
        if (fields == null || fieldName == null)
            return null;
        return fields.get(fieldName);
    }

    private void setFilename(String s) {
        if (s == null)
            return;

        int pos = s.indexOf("filename=\"");

        if (pos != -1) {
            filepath = s.substring(pos + 10, s.length() - 1);
            // Windows browsers include the full path on the client
            // But Linux/Unix and Mac browsers only send the filename
            // test if this is from a Windows browser
            pos = filepath.lastIndexOf("\\");
            if (pos != -1)
                filename = filepath.substring(pos + 1);
            else
                filename = filepath;
        }
    }

    private void setContentType(String s) {
        if (s == null)
            return;

        int pos = s.indexOf(": ");

        if (pos != -1)
            contentType = s.substring(pos + 2, s.length());
    }

    public void doUpload(HttpServletRequest request) throws IOException {
        ServletInputStream in = request.getInputStream();

        /* System.out.println("Header:");
         Enumeration ee = request.getHeaderNames();
         while (ee.hasMoreElements()) {
         String ss = (String)ee.nextElement();
         System.out.println(ss + " = [" + request.getHeader(ss) + "]");
         }*/
        String reqLengthString = request.getHeader("content-length");

        System.out.println("expect " + reqLengthString + " bytes.");
        int requestLength = 0;

        try {
            requestLength = Integer.valueOf(reqLengthString).intValue();
        } catch (Exception e2) {
            e2.printStackTrace();
            return;
        }
        byte[] line = new byte[BUFFER_SIZE];

        int i = -1;

        i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
        requestLength -= i;
        if (i < 3)
            return;
        int boundaryLength = i - 2;

        String boundary = new String(line, 0, boundaryLength); // -2 discards the newline character

        System.out.println("boundary=[" + boundary + "] length is " + boundaryLength);
        fields = FastMap.newInstance();

        while (requestLength > 0/* i != -1*/) {
            String newLine = "";

            if (i > -1) {
                newLine = new String(line, 0, i);
            }
            if (newLine.startsWith("Content-Disposition: form-data; name=\"")) {
                if (newLine.indexOf("filename=\"") != -1) {
                    setFilename(new String(line, 0, i - 2));
                    if (filename == null)
                        return;
                    // this is the file content
                    i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                    requestLength -= i;

                    setContentType(new String(line, 0, i - 2));

                    // blank line
                    i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                    requestLength -= i;
                    newLine = new String(line, 0, i);
                    String filenameToUse = filename;

                    if (overrideFilename != null) {
                        filenameToUse = overrideFilename;
                    }

                    // first line of actual file
                    i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                    requestLength -= i;
                    newLine = new String(line, 0, i);

                    byte[] lastTwoBytes = new byte[2];

                    if (i > 1) {
                        lastTwoBytes[0] = line[i - 2];
                        lastTwoBytes[1] = line[i - 1];
                    }
                    System.out.println("about to create a file:" + (savePath == null ? "" : savePath) + filenameToUse);
                    // before creating the file make sure directory exists
                    File savePathFile = new File(savePath);
                    if (!savePathFile.exists()) {
                        savePathFile.mkdirs();
                    }
                    FileOutputStream fos = new FileOutputStream((savePath == null ? "" : savePath) + filenameToUse);
                    boolean bail = (new String(line, 0, i).startsWith(boundary));
                    boolean oneByteLine = (i == 1); // handle one-byte lines

                    while ((requestLength > 0/* i != -1*/) && !bail) {

                        // write the current buffer, except the last 2 bytes;
                        if (i > 1) {
                            fos.write(line, 0, i - 2);
                        }

                        oneByteLine = (i == 1); // we need to track on-byte lines differently

                        i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                        requestLength -= i;

                        // the problem is the last line of the file content
                        // contains the new line character.

                        // if the line just read was the last line, we're done.
                        // if not, we must write the last 2 bytes of the previous buffer
                        // just assume that a one-byte line isn't the last line

                        if (requestLength < 1) {
                            bail = true;
                        } else if (oneByteLine) {
                            fos.write(lastTwoBytes, 0, 1); // we only saved one byte
                        } else {
                            fos.write(lastTwoBytes, 0, 2);
                        }

                        if (i > 1) {
                            // save the last 2 bytes of the buffer
                            lastTwoBytes[0] = line[i - 2];
                            lastTwoBytes[1] = line[i - 1];
                        } else {
                            lastTwoBytes[0] = line[0]; // only save one byte
                        }
                    }
                    fos.flush();
                    fos.close();
                } else {
                    // this is a field
                    // get the field name
                    int pos = newLine.indexOf("name=\"");
                    String fieldName = newLine.substring(pos + 6, newLine.length() - 3);

                    // System.out.println("fieldName:" + fieldName);
                    // blank line
                    i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                    requestLength -= i;
                    i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                    requestLength -= i;
                    newLine = new String(line, 0, i);
                    StringBuilder fieldValue = new StringBuilder(BUFFER_SIZE);

                    while (requestLength > 0/* i != -1*/ && !newLine.startsWith(boundary)) {
                        // The last line of the field
                        // contains the new line character.
                        // So, we need to check if the current line is
                        // the last line.
                        i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
                        requestLength -= i;
                        if ((i == boundaryLength + 2 || i == boundaryLength + 4) // + 4 is eof
                            && (new String(line, 0, i).startsWith(boundary)))
                            fieldValue.append(newLine.substring(0, newLine.length() - 2));
                        else
                            fieldValue.append(newLine);
                        newLine = new String(line, 0, i);
                    }
                    // System.out.println("fieldValue:" + fieldValue.toString());
                    fields.put(fieldName, fieldValue.toString());
                }
            }
            i = waitingReadLine(in, line, 0, BUFFER_SIZE, requestLength);
            if (i > -1) {
                requestLength -= i;
            }

        } // end while
    }

    // reads a line, waiting if there is nothing available and reqLen > 0
    private int waitingReadLine(ServletInputStream in, byte[] buf, int off, int len, int reqLen) throws IOException {
        int i = -1;

        while (((i = in.readLine(buf, off, len)) == -1) && (reqLen > 0)) {
            System.out.print("waiting");
            if (waitCount > MAX_WAITS) {
                System.out.println("waited " + waitCount + " times, bailing out while still expecting " +
                    reqLen + " bytes.");
                throw new IOException("waited " + waitCount + " times, bailing out while still expecting " +
                        reqLen + " bytes.");
            }
            waitCount++;
            long endMS = new Date().getTime() + WAIT_INTERVAL;

            while (endMS > (new Date().getTime())) {
                try {
                    wait(WAIT_INTERVAL);
                } catch (Exception e3) {
                    System.out.print(".");
                }
            }
            System.out.println((new Date().getTime() - endMS) + " ms");
        }
        return i;
    }
}
