/*******************************************************************************
 * 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.HashMap;
import java.util.Map;

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

/**
 * 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 = new HashMap<String, String>();

        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;
    }
}
