/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed 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.axis.utils;

import org.apache.axis.AxisEngine;
import org.apache.axis.AxisProperties;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Class ByteArray
 */
public class ByteArray extends OutputStream {

    protected static double DEFAULT_CACHE_INCREMENT = 2.5;
    protected static int DEFAULT_RESIDENT_SIZE = 512 * 1024 * 1024; // 512 MB
    protected static boolean DEFAULT_ENABLE_BACKING_STORE = true;
    protected static int WORKING_BUFFER_SIZE = 8192;

    protected org.apache.axis.utils.ByteArrayOutputStream cache = null;

    protected int max_size = 0;
    protected File bs_handle = null;
    protected OutputStream bs_stream = null;
    protected long count = 0;
    protected boolean enableBackingStore = DEFAULT_ENABLE_BACKING_STORE;

    public boolean isEnableBackingStore() {
        return enableBackingStore;
    }

    public void setEnableBackingStore(boolean enableBackingStore) {
        this.enableBackingStore = enableBackingStore;
    }

    public static boolean isDEFAULT_ENABLE_BACKING_STORE() {
        return DEFAULT_ENABLE_BACKING_STORE;
    }

    public static void setDEFAULT_ENABLE_BACKING_STORE(
            boolean DEFAULT_ENABLE_BACKING_STORE) {
        ByteArray.DEFAULT_ENABLE_BACKING_STORE = DEFAULT_ENABLE_BACKING_STORE;
    }

    public static int getDEFAULT_RESIDENT_SIZE() {
        return DEFAULT_RESIDENT_SIZE;
    }

    public static void setDEFAULT_RESIDENT_SIZE(int DEFAULT_RESIDENT_SIZE) {
        ByteArray.DEFAULT_RESIDENT_SIZE = DEFAULT_RESIDENT_SIZE;
    }

    public static double getDEFAULT_CACHE_INCREMENT() {
        return DEFAULT_CACHE_INCREMENT;
    }

    public static void setDEFAULT_CACHE_INCREMENT(
            double DEFAULT_CACHE_INCREMENT) {
        ByteArray.DEFAULT_CACHE_INCREMENT = DEFAULT_CACHE_INCREMENT;
    }

    static {
        String value;
        value = AxisProperties.getProperty(
                AxisEngine.PROP_BYTE_BUFFER_CACHE_INCREMENT,
                "" + DEFAULT_CACHE_INCREMENT);
        DEFAULT_CACHE_INCREMENT = Double.parseDouble(value);
        value = AxisProperties.getProperty(
                AxisEngine.PROP_BYTE_BUFFER_RESIDENT_MAX_SIZE,
                "" + DEFAULT_RESIDENT_SIZE);
        DEFAULT_RESIDENT_SIZE = Integer.parseInt(value);
        value = AxisProperties.getProperty(
                AxisEngine.PROP_BYTE_BUFFER_WORK_BUFFER_SIZE,
                "" + WORKING_BUFFER_SIZE);
        WORKING_BUFFER_SIZE = Integer.parseInt(value);
        value =
                AxisProperties.getProperty(AxisEngine.PROP_BYTE_BUFFER_BACKING,
                        "" + DEFAULT_ENABLE_BACKING_STORE);
        if (value.equalsIgnoreCase("true") ||
                value.equals("1") ||
                value.equalsIgnoreCase("yes")) {
            DEFAULT_ENABLE_BACKING_STORE = true;
        } else {
            DEFAULT_ENABLE_BACKING_STORE = false;
        }
    }

    /**
     * Constructor ByteArray
     */
    public ByteArray() {
        this(DEFAULT_RESIDENT_SIZE);
    }

    /**
     * Constructor ByteArray
     *
     * @param max_resident_size
     */
    public ByteArray(int max_resident_size) {
        this(0, max_resident_size);
    }

    /**
     * Constructor ByteArray
     *
     * @param probable_size
     * @param max_resident_size
     */
    public ByteArray(int probable_size, int max_resident_size) {
        if (probable_size > max_resident_size) {
            probable_size = 0;
        }
        if (probable_size < WORKING_BUFFER_SIZE) {
            probable_size = WORKING_BUFFER_SIZE;
        }
        cache = new org.apache.axis.utils.ByteArrayOutputStream(probable_size);
        max_size = max_resident_size;
    }

    /**
     * Method write
     *
     * @param bytes
     * @throws IOException
     */
    public void write(byte bytes[]) throws IOException {
        write(bytes, 0, bytes.length);
    }

    /**
     * Method write
     *
     * @param bytes
     * @param start
     * @param length
     * @throws IOException
     */
    public void write(byte bytes[], int start, int length) throws IOException {
        count += length;
        if (cache != null) {
            increaseCapacity(length);
        }
        if (cache != null) {
            cache.write(bytes, start, length);
        } else if (bs_stream != null) {
            bs_stream.write(bytes, start, length);
        } else {
            throw new IOException("ByteArray does not have a backing store!");
        }
    }

    /**
     * Method write
     *
     * @param b
     * @throws IOException
     */
    public void write(int b) throws IOException {
        count += 1;
        if (cache != null) {
            increaseCapacity(1);
        }
        if (cache != null) {
            cache.write(b);
        } else if (bs_stream != null) {
            bs_stream.write(b);
        } else {
            throw new IOException("ByteArray does not have a backing store!");
        }
    }

    /**
     * Method close
     *
     * @throws IOException
     */
    public void close() throws IOException {
        if (bs_stream != null) {
            bs_stream.close();
            bs_stream = null;
        }
    }

    /**
     * Method size
     *
     * @return
     */
    public long size() {
        return count;
    }

    /**
     * Method flush
     *
     * @throws IOException
     */
    public void flush() throws IOException {
        if (bs_stream != null) {
            bs_stream.flush();
        }
    }

    /**
     * Method increaseCapacity
     *
     * @param count
     * @throws IOException
     */
    protected void increaseCapacity(int count) throws IOException {
        if (cache == null) {
            return;
        }
        if (count + cache.size() <= max_size) {
            return;
        } else if (enableBackingStore) {
            switchToBackingStore();
        } else {
            throw new IOException("ByteArray can not increase capacity by " +
                    count +
                    " due to max size limit of " + max_size);
        }
    }

    /**
     * Method discardBuffer
     */
    public synchronized void discardBuffer() {
        cache = null;
        if (bs_stream != null) {
            try {
                bs_stream.close();
            } catch (IOException e) {
                // just ignore it...
            }
            bs_stream = null;
        }
        discardBackingStore();
    }

    /**
     * Method makeInputStream
     *
     * @return
     * @throws IOException
     * @throws FileNotFoundException
     */
    protected InputStream makeInputStream()
            throws IOException, FileNotFoundException {
        close();
        if (cache != null) {
            return new ByteArrayInputStream(cache.toByteArray());
        } else if (bs_handle != null) {
            return createBackingStoreInputStream();
        } else {
            return null;
        }
    }

    /**
     * Method finalize
     */
    protected void finalize() {
        discardBuffer();
    }

    /**
     * Method switchToBackingStore
     *
     * @throws IOException
     */
    protected void switchToBackingStore() throws IOException {
        bs_handle = File.createTempFile("Axis", ".msg");
        bs_handle.createNewFile();
        bs_handle.deleteOnExit();
        bs_stream = new FileOutputStream(bs_handle);
        bs_stream.write(cache.toByteArray());
        cache = null;
    }

    /**
     * Method getBackingStoreFileName
     *
     * @throws IOException
     */
    public String getBackingStoreFileName() throws IOException {
        String fileName = null;
        if (bs_handle != null) {
            fileName = bs_handle.getCanonicalPath();
        }
        return fileName;
    }

    /**
     * Method discardBackingStore
     */
    protected void discardBackingStore() {
        if (bs_handle != null) {
            bs_handle.delete();
            bs_handle = null;
        }
    }

    /**
     * Method createBackingStoreInputStream
     *
     * @return
     * @throws FileNotFoundException
     */
    protected InputStream createBackingStoreInputStream()
            throws FileNotFoundException {
        try {
            return new BufferedInputStream(
                    new FileInputStream(bs_handle.getCanonicalPath()));
        } catch (IOException e) {
            throw new FileNotFoundException(bs_handle.getAbsolutePath());
        }
    }

    /**
     * Method toByteArray
     *
     * @return
     * @throws IOException
     */
    public byte[] toByteArray() throws IOException {
        InputStream inp = this.makeInputStream();
        byte[] buf = null;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        buf = new byte[WORKING_BUFFER_SIZE];
        int len;
        while ((len = inp.read(buf, 0, WORKING_BUFFER_SIZE)) != -1) {
            baos.write(buf, 0, len);
        }
        inp.close();
        discardBackingStore();
        return baos.toByteArray();
    }

    /**
     * Method writeTo
     *
     * @param os
     * @throws IOException
     */
    public void writeTo(OutputStream os) throws IOException {
        InputStream inp = this.makeInputStream();
        byte[] buf = null;
        buf = new byte[WORKING_BUFFER_SIZE];
        int len;
        while ((len = inp.read(buf, 0, WORKING_BUFFER_SIZE)) != -1) {
            os.write(buf, 0, len);
        }
        inp.close();
        discardBackingStore();
    }
}
