/*******************************************************************************
 * 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.apache.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();

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

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