/*
 * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.corba.se.impl.encoding;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ByteArrayOutputStream;

import java.nio.ByteBuffer;

import com.sun.corba.se.spi.orb.ORB;
import com.sun.corba.se.spi.ior.IOR;
import com.sun.corba.se.spi.ior.IORFactories;
import com.sun.corba.se.spi.ior.iiop.GIOPVersion;
import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.spi.presentation.rmi.StubAdapter;

import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.impl.orbutil.ORBUtility;
import com.sun.corba.se.impl.corba.TypeCodeImpl;
import com.sun.corba.se.impl.logging.ORBUtilSystemException;
import com.sun.corba.se.impl.protocol.giopmsgheaders.Message;

import org.omg.CORBA.Any;
import org.omg.CORBA.TypeCode;
import org.omg.CORBA.Principal;
import org.omg.CORBA.CompletionStatus;

/**
 * Implementation class that uses Java serialization for output streams.
 * This assumes a GIOP version 1.2 message format.
 *
 * This class uses a ByteArrayOutputStream as the underlying buffer. The
 * first 16 bytes are direct writes into the underlying buffer. This allows
 * [GIOPHeader (12 bytes) + requestID (4 bytes)] to be written as bytes.
 * Subsequent write operations on this output stream object uses
 * ObjectOutputStream class to write into the buffer. This allows marshaling
 * complex types and graphs using the ObjectOutputStream implementation.
 *
 * Note, this class assumes a GIOP 1.2 style header. Note, we expect that the
 * first 16 bytes are written only using the write_octet, write_long or
 * write_ulong method calls.
 *
 * @author Ram Jeyaraman
 */
final class IDLJavaSerializationOutputStream extends CDROutputStreamBase {

    private ORB orb;
    private byte encodingVersion;
    private ObjectOutputStream os;
    private _ByteArrayOutputStream bos;
    private BufferManagerWrite bufferManager;

    // [GIOPHeader(12) + requestID(4)] bytes
    private final int directWriteLength = Message.GIOPMessageHeaderLength + 4;

    protected ORBUtilSystemException wrapper;

    class _ByteArrayOutputStream extends ByteArrayOutputStream {

        _ByteArrayOutputStream(int initialSize) {
            super(initialSize);
        }

        byte[] getByteArray() {
            return this.buf;
        }
    }

    class MarshalObjectOutputStream extends ObjectOutputStream {

        ORB orb;

        MarshalObjectOutputStream(java.io.OutputStream out, ORB orb)
                throws IOException {

            super(out);
            this.orb = orb;
            java.security.AccessController.doPrivileged(
                new java.security.PrivilegedAction() {
                    public Object run() {
                        // needs SerializablePermission("enableSubstitution")
                        enableReplaceObject(true);
                        return null;
                    }
                }
            );
        }

        /**
         * Checks for objects that are instances of java.rmi.Remote
         * that need to be serialized as proxy (Stub) objects.
         */
        protected final Object replaceObject(Object obj) throws IOException {
            try {
                if ((obj instanceof java.rmi.Remote) &&
                        !(StubAdapter.isStub(obj))) {
                    return Utility.autoConnect(obj, orb, true);
                }
            } catch (Exception e) {
                IOException ie = new IOException("replaceObject failed");
                ie.initCause(e);
                throw ie;
            }
            return obj;
        }
    }

    public IDLJavaSerializationOutputStream(byte encodingVersion) {
        super();
        this.encodingVersion = encodingVersion;
    }

    public void init(org.omg.CORBA.ORB orb, boolean littleEndian,
                     BufferManagerWrite bufferManager,
                     byte streamFormatVersion,
                     boolean usePooledByteBuffers) {
        this.orb = (ORB) orb;
        this.bufferManager = bufferManager;
        wrapper = ORBUtilSystemException.get((ORB) orb,
                                             CORBALogDomains.RPC_ENCODING);
        bos =
            new _ByteArrayOutputStream(ORBConstants.GIOP_DEFAULT_BUFFER_SIZE);
    }

    // Called from read_octet or read_long or read_ulong method.
    private void initObjectOutputStream() {
        //System.out.print(" os ");
        if (os != null) {
            throw wrapper.javaStreamInitFailed();
        }
        try {
            os = new MarshalObjectOutputStream(bos, orb);
        } catch (Exception e) {
            throw wrapper.javaStreamInitFailed(e);
        }
    }

    // org.omg.CORBA.portable.OutputStream

    // Primitive types.

    public final void write_boolean(boolean value) {
        try {
            os.writeBoolean(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_boolean");
        }
    }

    public final void write_char(char value) {
        try {
            os.writeChar(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_char");
        }
    }

    public final void write_wchar(char value) {
        this.write_char(value);
    }

    public final void write_octet(byte value) {

        // check if size < [ GIOPHeader(12) + requestID(4)] bytes
        if (bos.size() < directWriteLength) {
            bos.write(value); // direct write.
            if (bos.size() == directWriteLength) {
                initObjectOutputStream();
            }
            return;
        }

        try {
            os.writeByte(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_octet");
        }
    }

    public final void write_short(short value) {
        try {
            os.writeShort(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_short");
        }
    }

    public final void write_ushort(short value) {
        this.write_short(value);
    }

    public final void write_long(int value) {

        // check if size < [ GIOPHeader(12) + requestID(4)] bytes
        if (bos.size() < directWriteLength) {

            // Use big endian (network byte order). This is fixed.
            // Both the writer and reader use the same byte order.
            bos.write((byte)((value >>> 24) & 0xFF));
            bos.write((byte)((value >>> 16) & 0xFF));
            bos.write((byte)((value >>> 8) & 0xFF));
            bos.write((byte)((value >>> 0) & 0xFF));

            if (bos.size() == directWriteLength) {
                initObjectOutputStream();
            } else if (bos.size() > directWriteLength) {
                // Cannot happen. All direct writes are contained
                // within the first 16 bytes.
                wrapper.javaSerializationException("write_long");
            }
            return;
        }

        try {
            os.writeInt(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_long");
        }
    }

    public final void write_ulong(int value) {
        this.write_long(value);
    }

    public final void write_longlong(long value) {
        try {
            os.writeLong(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_longlong");
        }
    }

    public final void write_ulonglong(long value) {
        this.write_longlong(value);
    }

    public final void write_float(float value) {
        try {
            os.writeFloat(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_float");
        }
    }

    public final void write_double(double value) {
        try {
            os.writeDouble(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_double");
        }
    }

    // String types.

    public final void write_string(String value) {
        try {
            os.writeUTF(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_string");
        }
    }

    public final void write_wstring(String value) {
        try {
            os.writeObject(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_wstring");
        }
    }

    // Array types.

    public final void write_boolean_array(boolean[] value,
                                          int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_boolean(value[offset + i]);
        }
    }

    public final void write_char_array(char[] value, int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_char(value[offset + i]);
        }
    }

    public final void write_wchar_array(char[] value, int offset, int length) {
        write_char_array(value, offset, length);
    }

    public final void write_octet_array(byte[] value, int offset, int length) {
        try {
            os.write(value, offset, length);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_octet_array");
        }
    }

    public final void write_short_array(short[] value,
                                        int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_short(value[offset + i]);
        }
    }

    public final void write_ushort_array(short[] value,
                                         int offset, int length){
        write_short_array(value, offset, length);
    }

    public final void write_long_array(int[] value, int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_long(value[offset + i]);
        }
    }

    public final void write_ulong_array(int[] value, int offset, int length) {
        write_long_array(value, offset, length);
    }

    public final void write_longlong_array(long[] value,
                                           int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_longlong(value[offset + i]);
        }
    }

    public final void write_ulonglong_array(long[] value,
                                            int offset,int length) {
        write_longlong_array(value, offset, length);
    }

    public final void write_float_array(float[] value,
                                        int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_float(value[offset + i]);
        }
    }

    public final void write_double_array(double[] value,
                                         int offset, int length) {
        for (int i = 0; i < length; i++) {
            write_double(value[offset + i]);
        }
    }

    // Complex types (objects and graphs).

    public final void write_Object(org.omg.CORBA.Object value) {
        if (value == null) {
            IOR nullIOR = IORFactories.makeIOR(orb);
            nullIOR.write(parent);
            return;
        }
        // IDL to Java formal 01-06-06 1.21.4.2
        if (value instanceof org.omg.CORBA.LocalObject) {
            throw wrapper.writeLocalObject(CompletionStatus.COMPLETED_MAYBE);
        }
        IOR ior = ORBUtility.connectAndGetIOR(orb, value);
        ior.write(parent);
        return;
    }

    public final void write_TypeCode(TypeCode tc) {
        if (tc == null) {
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
        }
        TypeCodeImpl tci;
        if (tc instanceof TypeCodeImpl) {
            tci = (TypeCodeImpl) tc;
        } else {
            tci = new TypeCodeImpl(orb, tc);
        }
        tci.write_value((org.omg.CORBA_2_3.portable.OutputStream) parent);
    }

    public final void write_any(Any any) {
        if (any == null) {
            throw wrapper.nullParam(CompletionStatus.COMPLETED_MAYBE);
        }
        write_TypeCode(any.type());
        any.write_value(parent);
    }

    public final void write_Principal(Principal p) {
        // We don't need an implementation for this method, since principal
        // is absent in GIOP version 1.2 or above.
        write_long(p.name().length);
        write_octet_array(p.name(), 0, p.name().length);
    }

    public final void write_fixed(java.math.BigDecimal bigDecimal) {
        // This string might contain sign and/or dot
        this.write_fixed(bigDecimal.toString(), bigDecimal.signum());
    }

    // The string may contain a sign and dot
    private void write_fixed(String string, int signum) {

        int stringLength = string.length();

        // Each octet contains (up to) two decimal digits.
        byte doubleDigit = 0;
        char ch;
        byte digit;

        // First calculate the string length without optional sign and dot.
        int numDigits = 0;
        for (int i=0; i<stringLength; i++) {
            ch = string.charAt(i);
            if (ch == '-' || ch == '+' || ch == '.')
                continue;
            numDigits++;
        }

        for (int i=0; i<stringLength; i++) {
            ch = string.charAt(i);
            if (ch == '-' || ch == '+' || ch == '.')
                continue;
            digit = (byte)Character.digit(ch, 10);
            if (digit == -1) {
                throw wrapper.badDigitInFixed(
                                            CompletionStatus.COMPLETED_MAYBE);
            }
            // If the fixed type has an odd number of decimal digits, then the
            // representation begins with the first (most significant) digit.
            // Otherwise, this first half-octet is all zero, and the first
            // digit is in the second half-octet.
            if (numDigits % 2 == 0) {
                doubleDigit |= digit;
                this.write_octet(doubleDigit);
                doubleDigit = 0;
            } else {
                doubleDigit |= (digit << 4);
            }
            numDigits--;
        }

        // The sign configuration in the last half-octet of the representation,
        // is 0xD for negative numbers and 0xC for positive and zero values.
        if (signum == -1) {
            doubleDigit |= 0xd;
        } else {
            doubleDigit |= 0xc;
        }
        this.write_octet(doubleDigit);
    }

    public final org.omg.CORBA.ORB orb() {
        return this.orb;
    }

    // org.omg.CORBA_2_3.portable.OutputStream

    public final void write_value(java.io.Serializable value) {
        write_value(value, (String) null);
    }

    public final void write_value(java.io.Serializable value,
                                  java.lang.Class clz) {
        write_value(value);
    }

    public final void write_value(java.io.Serializable value,
                                  String repository_id) {
        try {
            os.writeObject(value);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_value");
        }
    }

    public final void write_value(java.io.Serializable value,
                             org.omg.CORBA.portable.BoxedValueHelper factory) {
        this.write_value(value, (String) null);
    }

    public final void write_abstract_interface(java.lang.Object obj) {

        boolean isCorbaObject = false; // Assume value type.
        org.omg.CORBA.Object theCorbaObject = null;

        // Is it a CORBA.Object?
        if (obj != null && obj instanceof org.omg.CORBA.Object) {
            theCorbaObject = (org.omg.CORBA.Object)obj;
            isCorbaObject = true;
        }

        // Write the boolean flag.
        this.write_boolean(isCorbaObject);

        // Now write out the object.
        if (isCorbaObject) {
            write_Object(theCorbaObject);
        } else {
            try {
                write_value((java.io.Serializable)obj);
            } catch(ClassCastException cce) {
                if (obj instanceof java.io.Serializable) {
                    throw cce;
                } else {
                    ORBUtility.throwNotSerializableForCorba(
                                                    obj.getClass().getName());
                }
            }
        }
    }

    // com.sun.corba.se.os.encoding.MarshalOutputStream

    public final void start_block() {
        throw wrapper.giopVersionError();
    }

    public final void end_block() {
        throw wrapper.giopVersionError();
    }

    public final void putEndian() {
        throw wrapper.giopVersionError();
    }

    public void writeTo(java.io.OutputStream s) throws IOException {
        try {
            os.flush();
            bos.writeTo(s);
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "writeTo");
        }
    }

    public final byte[] toByteArray() {
        try {
            os.flush();
            return bos.toByteArray(); // new copy.
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "toByteArray");
        }
    }

    // org.omg.CORBA.DataOutputStream

    public final void write_Abstract (java.lang.Object value) {
        write_abstract_interface(value);
    }

    public final void write_Value(java.io.Serializable value) {
        write_value(value);
    }

    public final void write_any_array(org.omg.CORBA.Any[] value,
                                      int offset, int length) {
        for(int i = 0; i < length; i++) {
            write_any(value[offset + i]);
        }
    }

    // org.omg.CORBA.portable.ValueBase

    public final String[] _truncatable_ids() {
        throw wrapper.giopVersionError();
    }

    // Other.

    public final int getSize() {
        try {
            os.flush();
            return bos.size();
        } catch (Exception e) {
            throw wrapper.javaSerializationException(e, "write_boolean");
        }
    }

    public final int getIndex() {
        return getSize();
    }

    protected int getRealIndex(int index) {
        return getSize();
    }

    public final void setIndex(int value) {
        throw wrapper.giopVersionError();
    }

    public final ByteBuffer getByteBuffer() {
        throw wrapper.giopVersionError();
    }

    public final void setByteBuffer(ByteBuffer byteBuffer) {
        throw wrapper.giopVersionError();
    }

    public final boolean isLittleEndian() {
        // Java serialization uses network byte order, that is, big-endian.
        return false;
    }

    public ByteBufferWithInfo getByteBufferWithInfo() {
        try {
            os.flush();
        } catch (Exception e) {
            throw wrapper.javaSerializationException(
                                            e, "getByteBufferWithInfo");
        }
        ByteBuffer byteBuffer = ByteBuffer.wrap(bos.getByteArray());
        byteBuffer.limit(bos.size());
        return new ByteBufferWithInfo(this.orb, byteBuffer, bos.size());
    }

    public void setByteBufferWithInfo(ByteBufferWithInfo bbwi) {
        throw wrapper.giopVersionError();
    }

    public final BufferManagerWrite getBufferManager() {
        return bufferManager;
    }

    // This will stay a custom add-on until the java-rtf issue is resolved.
    // Then it should be declared in org.omg.CORBA.portable.OutputStream.
    //
    // Pads the string representation of bigDecimal with zeros to fit the given
    // digits and scale before it gets written to the stream.
    public final void write_fixed(java.math.BigDecimal bigDecimal,
                                  short digits, short scale) {
        String string = bigDecimal.toString();
        String integerPart;
        String fractionPart;
        StringBuffer stringBuffer;

        // Get rid of the sign
        if (string.charAt(0) == '-' || string.charAt(0) == '+') {
            string = string.substring(1);
        }

        // Determine integer and fraction parts
        int dotIndex = string.indexOf('.');
        if (dotIndex == -1) {
            integerPart = string;
            fractionPart = null;
        } else if (dotIndex == 0 ) {
            integerPart = null;
            fractionPart = string;
        } else {
            integerPart = string.substring(0, dotIndex);
            fractionPart = string.substring(dotIndex + 1);
        }

        // Pad both parts with zeros as necessary
        stringBuffer = new StringBuffer(digits);
        if (fractionPart != null) {
            stringBuffer.append(fractionPart);
        }
        while (stringBuffer.length() < scale) {
            stringBuffer.append('0');
        }
        if (integerPart != null) {
            stringBuffer.insert(0, integerPart);
        }
        while (stringBuffer.length() < digits) {
            stringBuffer.insert(0, '0');
        }

        // This string contains no sign or dot
        this.write_fixed(stringBuffer.toString(), bigDecimal.signum());
    }

    public final void writeOctetSequenceTo(
            org.omg.CORBA.portable.OutputStream s) {
        byte[] buf = this.toByteArray(); // new copy.
        s.write_long(buf.length);
        s.write_octet_array(buf, 0, buf.length);
    }

    public final GIOPVersion getGIOPVersion() {
        return GIOPVersion.V1_2;
    }

    public final void writeIndirection(int tag, int posIndirectedTo) {
        throw wrapper.giopVersionError();
    }

    void freeInternalCaches() {}

    void printBuffer() {
        byte[] buf = this.toByteArray();

        System.out.println("+++++++ Output Buffer ++++++++");
        System.out.println();
        System.out.println("Current position: " + buf.length);
        //System.out.println("Total length : " + buf.length);
        System.out.println();

        char[] charBuf = new char[16];

        try {

            for (int i = 0; i < buf.length; i += 16) {

                int j = 0;

                // For every 16 bytes, there is one line
                // of output.  First, the hex output of
                // the 16 bytes with each byte separated
                // by a space.
                while (j < 16 && j + i < buf.length) {
                    int k = buf[i + j];
                    if (k < 0)
                        k = 256 + k;
                    String hex = Integer.toHexString(k);
                    if (hex.length() == 1)
                        hex = "0" + hex;
                    System.out.print(hex + " ");
                    j++;
                }

                // Add any extra spaces to align the
                // text column in case we didn't end
                // at 16
                while (j < 16) {
                    System.out.print("   ");
                    j++;
                }

                // Now output the ASCII equivalents.  Non-ASCII
                // characters are shown as periods.
                int x = 0;

                while (x < 16 && x + i < buf.length) {
                    if (ORBUtility.isPrintable((char)buf[i + x])) {
                        charBuf[x] = (char) buf[i + x];
                    } else {
                        charBuf[x] = '.';
                    }
                    x++;
                }
                System.out.println(new String(charBuf, 0, x));
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("++++++++++++++++++++++++++++++");
    }

    public void alignOnBoundary(int octetBoundary) {
        throw wrapper.giopVersionError();
    }

    // Needed by request and reply messages for GIOP versions >= 1.2 only.
    public void setHeaderPadding(boolean headerPadding) {
        // no-op. We don't care about body alignment while using
        // Java serialization. What the GIOP spec states does not apply here.
    }

    // ValueOutputStream -----------------------------

    public void start_value(String rep_id) {
        throw wrapper.giopVersionError();
    }

    public void end_value() {
        throw wrapper.giopVersionError();
    }

    // java.io.OutputStream

    // Note: These methods are defined in the super class and accessible.

    //public abstract void write(byte b[]) throws IOException;
    //public abstract void write(byte b[], int off, int len)
    //    throws IOException;
    //public abstract void flush() throws IOException;
    //public abstract void close() throws IOException;
}
