/*
 * 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.commons.fileupload;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;


/**
 * Unit test for items with varying sizes.
 */
public class SizesTest extends FileUploadTestCase
{
	/** Runs a test with varying file sizes.
	 */
	public void testFileUpload()
            throws IOException, FileUploadException
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int add = 16;
        int num = 0;
        for (int i = 0;  i < 16384;  i += add) {
            if (++add == 32) {
                add = 16;
            }
            String header = "-----1234\r\n"
                + "Content-Disposition: form-data; name=\"field" + (num++) + "\"\r\n"
                + "\r\n";
            baos.write(header.getBytes("US-ASCII"));
            for (int j = 0;  j < i;  j++) {
                baos.write((byte) j);
            }
            baos.write("\r\n".getBytes("US-ASCII"));
        }
        baos.write("-----1234--\r\n".getBytes("US-ASCII"));

        List fileItems = parseUpload(baos.toByteArray());
        Iterator fileIter = fileItems.iterator();
        add = 16;
        num = 0;
        for (int i = 0;  i < 16384;  i += add) {
            if (++add == 32) {
                add = 16;
            }
            FileItem item = (FileItem) fileIter.next();
            assertEquals("field" + (num++), item.getFieldName());
            byte[] bytes = item.get();
            assertEquals(i, bytes.length);
            for (int j = 0;  j < i;  j++) {
                assertEquals((byte) j, bytes[j]);
            }
        }
        assertTrue(!fileIter.hasNext());
    }

	/** Checks, whether limiting the file size works.
	 */
	public void testFileSizeLimit()
            throws IOException, FileUploadException
    {
		final String request =
			"-----1234\r\n" +
			"Content-Disposition: form-data; name=\"file\"; filename=\"foo.tab\"\r\n" +
			"Content-Type: text/whatever\r\n" +
			"\r\n" +
			"This is the content of the file\n" +
			"\r\n" +
			"-----1234--\r\n";

		ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
		upload.setFileSizeMax(-1);
        HttpServletRequest req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE);
        List fileItems = upload.parseRequest(req);
        assertEquals(1, fileItems.size());
        FileItem item = (FileItem) fileItems.get(0);
        assertEquals("This is the content of the file\n", new String(item.get()));
        
		upload = new ServletFileUpload(new DiskFileItemFactory());
		upload.setFileSizeMax(40);
        req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE);
        fileItems = upload.parseRequest(req);
        assertEquals(1, fileItems.size());
        item = (FileItem) fileItems.get(0);
        assertEquals("This is the content of the file\n", new String(item.get()));

		upload = new ServletFileUpload(new DiskFileItemFactory());
		upload.setFileSizeMax(30);
        req = new MockHttpServletRequest(request.getBytes("US-ASCII"), CONTENT_TYPE);
        try {
        	upload.parseRequest(req);
        	fail("Expected exception.");
        } catch (FileUploadBase.FileSizeLimitExceededException e) {
        	assertEquals(30, e.getPermittedSize());
        }
    }
}
