/*
 * 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.
 */
/*
 * $Id$
 */
package org.apache.xml.serializer;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;

/**
 * This class wraps the real writer, it only purpose is to send
 * CHARACTERTOSTREAM events to the trace listener. 
 * Each method immediately sends the call to the wrapped writer unchanged, but
 * in addition it collects characters to be issued to a trace listener.
 * 
 * In this way the trace
 * listener knows what characters have been written to the output Writer.
 * 
 * There may still be differences in what the trace events say is going to the
 * output writer and what is really going there. These differences will be due
 * to the fact that this class is UTF-8 encoding before emiting the trace event
 * and the underlying writer may not be UTF-8 encoding. There may also be
 * encoding differences.  So the main pupose of this class is to provide a
 * resonable facsimile of the true output.
 * 
 * @xsl.usage internal
 */
final class SerializerTraceWriter extends Writer implements WriterChain
{

    /** The real writer to immediately write to.
     * This reference may be null, in which case nothing is written out, but
     * only the trace events are fired for output.
     */
    private final java.io.Writer m_writer;

    /** The tracer to send events to */
    private final SerializerTrace m_tracer;

    /** The size of the internal buffer, just to keep too many
     * events from being sent to the tracer
     */
    private int buf_length;

    /**
     * Internal buffer to collect the characters to go to the trace listener.
     * 
     */
    private byte buf[];

    /**
     * How many bytes have been collected and still need to go to trace
     * listener.
     */
    private int count;

    /**
     * Creates or replaces the internal buffer, and makes sure it has a few
     * extra bytes slight overflow of the last UTF8 encoded character.
     * @param size
     */
    private void setBufferSize(int size)
    {
        buf = new byte[size + 3];
        buf_length = size;
        count = 0;
    }

    /**
     * Constructor.
     * If the writer passed in is null, then this SerializerTraceWriter will
     * only signal trace events of what would have been written to that writer.
     * If the writer passed in is not null then the trace events will mirror
     * what is going to that writer. In this way tools, such as a debugger, can
     * gather information on what is being written out.
     * 
     * @param out the Writer to write to (possibly null)
     * @param tracer the tracer to inform that characters are being written
     */
    public SerializerTraceWriter(Writer out, SerializerTrace tracer)
    {
        m_writer = out;
        m_tracer = tracer;
        setBufferSize(1024);
    }

    /**
     * Flush out the collected characters by sending them to the trace
     * listener.  These characters are never written to the real writer
     * (m_writer) because that has already happened with every method
     * call. This method simple informs the listener of what has already
     * happened.
     * @throws IOException
     */
    private void flushBuffer() throws IOException
    {

        // Just for tracing purposes
        if (count > 0)
        {
            char[] chars = new char[count];
            for(int i=0; i<count; i++)
                chars[i] = (char) buf[i];

            if (m_tracer != null)
                m_tracer.fireGenerateEvent(
                    SerializerTrace.EVENTTYPE_OUTPUT_CHARACTERS,
                    chars,
                    0,
                    chars.length);

            count = 0;
        }
    }

    /**
     * Flush the internal buffer and flush the Writer
     * @see java.io.Writer#flush()
     */
    public void flush() throws java.io.IOException
    {
        // send to the real writer
        if (m_writer != null)
            m_writer.flush();

        // from here on just for tracing purposes
        flushBuffer();
    }

    /**
     * Flush the internal buffer and close the Writer
     * @see java.io.Writer#close()
     */
    public void close() throws java.io.IOException
    {
        // send to the real writer
        if (m_writer != null)   
            m_writer.close();

        // from here on just for tracing purposes
        flushBuffer();
    }


    /**
     * Write a single character.  The character to be written is contained in
     * the 16 low-order bits of the given integer value; the 16 high-order bits
     * are ignored.
     *
     * <p> Subclasses that intend to support efficient single-character output
     * should override this method.
     *
     * @param c  int specifying a character to be written.
     * @exception  IOException  If an I/O error occurs
     */
    public void write(final int c) throws IOException
    {
        // send to the real writer
        if (m_writer != null)
            m_writer.write(c);

        // ---------- from here on just collect for tracing purposes

        /* If we are close to the end of the buffer then flush it.
         * Remember the buffer can hold a few more characters than buf_length
         */
        if (count >= buf_length)
            flushBuffer();

        if (c < 0x80)
        {
            buf[count++] = (byte) (c);
        }
        else if (c < 0x800)
        {
            buf[count++] = (byte) (0xc0 + (c >> 6));
            buf[count++] = (byte) (0x80 + (c & 0x3f));
        }
        else
        {
            buf[count++] = (byte) (0xe0 + (c >> 12));
            buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
            buf[count++] = (byte) (0x80 + (c & 0x3f));
        }
    }

    /**
     * Write a portion of an array of characters.
     *
     * @param  chars  Array of characters
     * @param  start   Offset from which to start writing characters
     * @param  length   Number of characters to write
     *
     * @exception  IOException  If an I/O error occurs
     *
     * @throws java.io.IOException
     */
    public void write(final char chars[], final int start, final int length)
        throws java.io.IOException
    {
        // send to the real writer
        if (m_writer != null)
            m_writer.write(chars, start, length);

        // from here on just collect for tracing purposes
        int lengthx3 = (length << 1) + length;

        if (lengthx3 >= buf_length)
        {

            /* If the request length exceeds the size of the output buffer,
              * flush the output buffer and make the buffer bigger to handle.
              */

            flushBuffer();
            setBufferSize(2 * lengthx3);

        }

        if (lengthx3 > buf_length - count)
        {
            flushBuffer();
        }

        final int n = length + start;
        for (int i = start; i < n; i++)
        {
            final char c = chars[i];

            if (c < 0x80)
                buf[count++] = (byte) (c);
            else if (c < 0x800)
            {
                buf[count++] = (byte) (0xc0 + (c >> 6));
                buf[count++] = (byte) (0x80 + (c & 0x3f));
            }
            else
            {
                buf[count++] = (byte) (0xe0 + (c >> 12));
                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
                buf[count++] = (byte) (0x80 + (c & 0x3f));
            }
        }

    }

    /**
     * Write a string.
     *
     * @param  s  String to be written
     *
     * @exception  IOException  If an I/O error occurs
     */
    public void write(final String s) throws IOException
    {
        // send to the real writer
        if (m_writer != null)
            m_writer.write(s);

        // from here on just collect for tracing purposes
        final int length = s.length();

        // We multiply the length by three since this is the maximum length
        // of the characters that we can put into the buffer.  It is possible
        // for each Unicode character to expand to three bytes.

        int lengthx3 = (length << 1) + length;

        if (lengthx3 >= buf_length)
        {

            /* If the request length exceeds the size of the output buffer,
              * flush the output buffer and make the buffer bigger to handle.
              */

            flushBuffer();
            setBufferSize(2 * lengthx3);
        }

        if (lengthx3 > buf_length - count)
        {
            flushBuffer();
        }

        for (int i = 0; i < length; i++)
        {
            final char c = s.charAt(i);

            if (c < 0x80)
                buf[count++] = (byte) (c);
            else if (c < 0x800)
            {
                buf[count++] = (byte) (0xc0 + (c >> 6));
                buf[count++] = (byte) (0x80 + (c & 0x3f));
            }
            else
            {
                buf[count++] = (byte) (0xe0 + (c >> 12));
                buf[count++] = (byte) (0x80 + ((c >> 6) & 0x3f));
                buf[count++] = (byte) (0x80 + (c & 0x3f));
            }
        }
    }

    /**
     * Get the writer that this one directly wraps.
     */
    public Writer getWriter()
    {
        return m_writer;
    }

    /**
     * Get the OutputStream that is the at the end of the
     * chain of writers.
     */
    public OutputStream getOutputStream()
    {
        OutputStream retval = null;
        if (m_writer instanceof WriterChain)
            retval = ((WriterChain) m_writer).getOutputStream();
        return retval;
    }
}
