/*
 *  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.tomcat.util.buf;

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

/** Efficient conversion of character to bytes.
 *  
 *  This uses the standard JDK mechansim - a writer - but provides mechanisms
 *  to recycle all the objects that are used. It is compatible with JDK1.1 and up,
 *  ( nio is better, but it's not available even in 1.2 or 1.3 )
 * 
 */
public final class C2BConverter {
    
    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog(C2BConverter.class );
    
    private IntermediateOutputStream ios;
    private WriteConvertor conv;
    private ByteChunk bb;
    private String enc;
    
    /** Create a converter, with bytes going to a byte buffer
     */
    public C2BConverter(ByteChunk output, String encoding) throws IOException {
	this.bb=output;
	ios=new IntermediateOutputStream( output );
	conv=new WriteConvertor( ios, encoding );
        this.enc=encoding;
    }

    /** Create a converter
     */
    public C2BConverter(String encoding) throws IOException {
	this( new ByteChunk(1024), encoding );
    }

    public ByteChunk getByteChunk() {
	return bb;
    }

    public String getEncoding() {
        return enc;
    }

    public void setByteChunk(ByteChunk bb) {
	this.bb=bb;
	ios.setByteChunk( bb );
    }

    /** Reset the internal state, empty the buffers.
     *  The encoding remain in effect, the internal buffers remain allocated.
     */
    public  final void recycle() {
	conv.recycle();
	bb.recycle();
    }

    /** Generate the bytes using the specified encoding
     */
    public  final void convert(char c[], int off, int len ) throws IOException {
	conv.write( c, off, len );
    }

    /** Generate the bytes using the specified encoding
     */
    public  final void convert(String s ) throws IOException {
	conv.write( s );
    }

    /** Generate the bytes using the specified encoding
     */
    public  final void convert(char c ) throws IOException {
	conv.write( c );
    }

    /** Convert a message bytes chars to bytes
     */
    public final void convert(MessageBytes mb ) throws IOException {
        int type=mb.getType();
        if( type==MessageBytes.T_BYTES )
            return;
        ByteChunk orig=bb;
        setByteChunk( mb.getByteChunk());
        bb.recycle();
        bb.allocate( 32, -1 );
        
        if( type==MessageBytes.T_STR ) {
            convert( mb.getString() );
            // System.out.println("XXX Converting " + mb.getString() );
        } else if( type==MessageBytes.T_CHARS ) {
            CharChunk charC=mb.getCharChunk();
            convert( charC.getBuffer(),
                                charC.getOffset(), charC.getLength());
            //System.out.println("XXX Converting " + mb.getCharChunk() );
        } else {
            if (log.isDebugEnabled())
                log.debug("XXX unknowon type " + type );
        }
        flushBuffer();
        //System.out.println("C2B: XXX " + bb.getBuffer() + bb.getLength()); 
        setByteChunk(orig);
    }

    /** Flush any internal buffers into the ByteOutput or the internal
     *  byte[]
     */
    public  final void flushBuffer() throws IOException {
	conv.flush();
    }

}

// -------------------- Private implementation --------------------



/**
 *  Special writer class, where close() is overritten. The default implementation
 *  would set byteOutputter to null, and the writter can't be recycled. 
 *
 *  Note that the flush method will empty the internal buffers _and_ call
 *  flush on the output stream - that's why we use an intermediary output stream
 *  that overrides flush(). The idea is to  have full control: flushing the
 *  char->byte converter should be independent of flushing the OutputStream.
 * 
 *  When a WriteConverter is created, it'll allocate one or 2 byte buffers,
 *  with a 8k size that can't be changed ( at least in JDK1.1 -> 1.4 ). It would
 *  also allocate a ByteOutputter or equivalent - again some internal buffers.
 *
 *  It is essential to keep  this object around and reuse it. You can use either
 *  pools or per thread data - but given that in most cases a converter will be
 *  needed for every thread and most of the time only 1 ( or 2 ) encodings will
 *  be used, it is far better to keep it per thread and eliminate the pool 
 *  overhead too.
 * 
 */
 final class	WriteConvertor extends OutputStreamWriter {
    // stream with flush() and close(). overriden.
    private IntermediateOutputStream ios;
    
    // Has a private, internal byte[8192]
    
    /** Create a converter.
     */
    public WriteConvertor( IntermediateOutputStream out, String enc )
	throws UnsupportedEncodingException
    {
	super( out, enc );
	ios=out;
    }
    
    /** Overriden - will do nothing but reset internal state.
     */
    public  final void close() throws IOException {
	// NOTHING
	// Calling super.close() would reset out and cb.
    }
    
    /**
     *  Flush the characters only
     */ 
    public  final void flush() throws IOException {
	// Will flushBuffer and out()
	// flushBuffer put any remaining chars in the byte[] 
	super.flush();
    }
    
    public  final void write(char cbuf[], int off, int len) throws IOException {
	// will do the conversion and call write on the output stream
	super.write( cbuf, off, len );
    }
    
    /** Reset the buffer
     */
    public  final void recycle() {
	ios.disable();
	try {
	    //	    System.out.println("Reseting writer");
	    flush();
	} catch( Exception ex ) {
	    ex.printStackTrace();
	}
	ios.enable();
    }
    
}


/** Special output stream where close() is overriden, so super.close()
    is never called.
    
    This allows recycling. It can also be disabled, so callbacks will
    not be called if recycling the converter and if data was not flushed.
*/
final class IntermediateOutputStream extends OutputStream {
    private ByteChunk tbuff;
    private boolean enabled=true;
    
    public IntermediateOutputStream(ByteChunk tbuff) {
	    this.tbuff=tbuff;
    }
    
    public  final void close() throws IOException {
	// shouldn't be called - we filter it out in writer
	throw new IOException("close() called - shouldn't happen ");
    }
    
    public  final void flush() throws IOException {
	// nothing - write will go directly to the buffer,
	// we don't keep any state
    }
    
    public  final  void write(byte cbuf[], int off, int len) throws IOException {
	// will do the conversion and call write on the output stream
	if( enabled ) {
	    tbuff.append( cbuf, off, len );
	}
    }
    
    public  final void write( int i ) throws IOException {
	throw new IOException("write( int ) called - shouldn't happen ");
    }

    // -------------------- Internal methods --------------------

    void setByteChunk( ByteChunk bb ) {
	tbuff=bb;
    }
    
    /** Temporary disable - this is used to recycle the converter without
     *  generating an output if the buffers were not flushed
     */
    final void disable() {
	enabled=false;
    }

    /** Reenable - used to recycle the converter
     */
    final void enable() {
	enabled=true;
    }
}
