/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * 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 com.alibaba.dubbo.common.io;

import java.io.IOException;
import java.io.InputStream;

/**
 * Stream utils.
 * 
 * @author qian.lei
 * @author ding.lid
 */

public class StreamUtils
{
	private StreamUtils(){}

	public static InputStream limitedInputStream(final InputStream is, final int limit) throws IOException
	{
		return new InputStream(){
			private int mPosition = 0, mMark = 0, mLimit = Math.min(limit, is.available());

			public int read() throws IOException
			{
				if( mPosition < mLimit )
				{
					mPosition++;
					return is.read();
				}
				return -1;
		    }

			public int read(byte b[], int off, int len) throws IOException
			{
				if( b == null )
				    throw new NullPointerException();

				if( off < 0 || len < 0 || len > b.length - off )
				    throw new IndexOutOfBoundsException();

				if( mPosition >= mLimit )
				    return -1;

				if( mPosition + len > mLimit )
				    len = mLimit - mPosition;

				if( len <= 0 )
				    return 0;

				is.read(b, off, len);
				mPosition += len;
				return len;
		    }

			public long skip(long len) throws IOException
		    {
				if( mPosition + len > mLimit )
					len = mLimit - mPosition;

				if( len <= 0 )
					return 0;

				is.skip(len);
				mPosition += len;
				return len;
		    }

			public int available()
			{
				return mLimit - mPosition;
			}

			public boolean markSupported()
		    {
		    	return is.markSupported();
			}

			public void mark(int readlimit)
			{
				is.mark(readlimit);
				mMark = mPosition;
			}

			public void reset() throws IOException
			{
				is.reset();
				mPosition = mMark;
			}

			public void close() throws IOException
			{}
		};
	}
	
	public static InputStream markSupportedInputStream(final InputStream is, final int markBufferSize) {
	    if(is.markSupported()) {
	        return is;
	    }

        return new InputStream() {
            byte[] mMarkBuffer;
            
            boolean mInMarked = false;
            boolean mInReset = false;
            private int mPosition = 0;
            private int mCount = 0;

            boolean mDry = false;
            
            @Override
            public int read() throws IOException {
                if(!mInMarked) {
                    return is.read();
                }
                else {
                    if(mPosition < mCount) {
                        byte b = mMarkBuffer[mPosition++];
                        return b & 0xFF;
                    }
                    
                    if(!mInReset) {
                        if(mDry) return -1;
                        
                        if(null == mMarkBuffer) {
                            mMarkBuffer = new byte[markBufferSize];
                        }
                        if(mPosition >= markBufferSize) {
                            throw new IOException("Mark buffer is full!");
                        }
                        
                        int read = is.read();
                        if(-1 == read){
                            mDry = true;
                            return -1;
                        }
                        
                        mMarkBuffer[mPosition++] = (byte) read;
                        mCount++;
                        
                        return read;
                    }
                    else {
                        // mark buffer is used, exit mark status!
                        mInMarked = false;
                        mInReset = false;
                        mPosition = 0;
                        mCount = 0;
                        
                        return is.read();
                    }
                }
            }

            /**
             * NOTE: the <code>readlimit</code> argument for this class
             *  has no meaning.
             */
            @Override
            public synchronized void mark(int readlimit) {
                mInMarked = true;
                mInReset = false;
                
                // mark buffer is not empty
                int count = mCount - mPosition;
                if(count > 0) {
                    System.arraycopy(mMarkBuffer, mPosition, mMarkBuffer, 0, count);
                    mCount = count;
                    mPosition = 0;
                }
            }
            
            @Override
            public synchronized void reset() throws IOException {
                if(!mInMarked) {
                    throw new IOException("should mark befor reset!");
                }
                
                mInReset = true;
                mPosition = 0;
            }
            
            @Override
            public boolean markSupported() {
                return true;
            }
            
            @Override
            public int available() throws IOException {
                int available = is.available();
                
                if(mInMarked && mInReset) available += mCount - mPosition;
                
                return available;
            }
        };
	}
	
	public static InputStream markSupportedInputStream(final InputStream is) {
	    return markSupportedInputStream(is, 1024);
	}
}