/**************************************************************
 * 
 * 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 com.sun.star.lib.uno.protocols.urp;

import com.sun.star.lib.uno.environments.remote.ThreadId;
import com.sun.star.lib.uno.typedesc.TypeDescription;
import com.sun.star.uno.Any;
import com.sun.star.uno.Enum;
import com.sun.star.uno.IBridge;
import com.sun.star.uno.IFieldDescription;
import com.sun.star.uno.Type;
import com.sun.star.uno.TypeClass;
import com.sun.star.uno.XInterface;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;

final class Unmarshal {
    public Unmarshal(IBridge bridge, int cacheSize) {
        this.bridge = bridge;
        objectIdCache = new String[cacheSize];
        threadIdCache = new ThreadId[cacheSize];
        typeCache = new TypeDescription[cacheSize];
        reset(new byte[0]);
    }

    public int read8Bit() {
        try {
            return input.readUnsignedByte();
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    public int read16Bit() {
        try {
            return input.readUnsignedShort();
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    public String readObjectId() {
        String id = readStringValue();
        int index = read16Bit();
        if (index == 0xFFFF) {
            if (id.length() == 0) {
                id = null;
            }
        } else {
            if (id.length() == 0) {
                id = objectIdCache[index];
            } else {
                objectIdCache[index] = id;
            }
        }
        return id;
    }

    public Object readInterface(Type type) {
        String id = readObjectId();
        return id == null ? null : bridge.mapInterfaceFrom(id, type);
    }

    public ThreadId readThreadId() {
        int len = readCompressedNumber();
        byte[] data  ;
        ThreadId id = null;
        if (len != 0) {
            data = new byte[len];
            readBytes(data);
            id = new ThreadId(data);
        }
        int index = read16Bit();
        if (index != 0xFFFF) {
            if (len == 0) {
                id = threadIdCache[index];
            } else {
                threadIdCache[index] = id;
            }
        }
        return id;
    }

    public TypeDescription readType() {
        int b = read8Bit();
        TypeClass typeClass = TypeClass.fromInt(b & 0x7F);
        if (TypeDescription.isTypeClassSimple(typeClass)) {
            return TypeDescription.getTypeDescription(typeClass);
        } else {
            int index = read16Bit();
            TypeDescription type = null;
            if ((b & 0x80) != 0) {
                try {
                    type = TypeDescription.getTypeDescription(
                        readStringValue());
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException(e.toString());
                }
            }
            if (index != 0xFFFF) {
                if ((b & 0x80) == 0) {
                    type = typeCache[index];
                } else {
                    typeCache[index] = type;
                }
            }
            return type;
        }
    }

    public Object readValue(TypeDescription type) {
        switch (type.getTypeClass().getValue()) {
        case TypeClass.VOID_value:
            return null;

        case TypeClass.BOOLEAN_value:
            return readBooleanValue();

        case TypeClass.BYTE_value:
            return readByteValue();

        case TypeClass.SHORT_value:
        case TypeClass.UNSIGNED_SHORT_value:
            return readShortValue();

        case TypeClass.LONG_value:
        case TypeClass.UNSIGNED_LONG_value:
            return readLongValue();

        case TypeClass.HYPER_value:
        case TypeClass.UNSIGNED_HYPER_value:
            return readHyperValue();

        case TypeClass.FLOAT_value:
            return readFloatValue();

        case TypeClass.DOUBLE_value:
            return readDoubleValue();

        case TypeClass.CHAR_value:
            return readCharValue();

        case TypeClass.STRING_value:
            return readStringValue();

        case TypeClass.TYPE_value:
            return readTypeValue();

        case TypeClass.ANY_value:
            return readAnyValue();

        case TypeClass.SEQUENCE_value:
            return readSequenceValue(type);

        case TypeClass.ENUM_value:
            return readEnumValue(type);

        case TypeClass.STRUCT_value:
            return readStructValue(type);

        case TypeClass.EXCEPTION_value:
            return readExceptionValue(type);

        case TypeClass.INTERFACE_value:
            return readInterfaceValue(type);

        default:
            throw new IllegalArgumentException("Bad type descriptor " + type);
        }
    }

    public boolean hasMore() {
        try {
            return input.available() > 0;
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    public void reset(byte[] data) {
        input = new DataInputStream(new ByteArrayInputStream(data));
    }

    private Boolean readBooleanValue() {
        try {
            return input.readBoolean() ? Boolean.TRUE : Boolean.FALSE;
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Byte readByteValue() {
        try {
            return new Byte(input.readByte());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Short readShortValue() {
        try {
            return new Short(input.readShort());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Integer readLongValue() {
        try {
            return new Integer(input.readInt());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Long readHyperValue() {
        try {
            return new Long(input.readLong());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Float readFloatValue() {
        try {
            return new Float(input.readFloat());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Double readDoubleValue() {
        try {
            return new Double(input.readDouble());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Character readCharValue() {
        try {
            return new Character(input.readChar());
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private String readStringValue() {
        int len = readCompressedNumber();
        byte[] data = new byte[len];
        readBytes(data);
        try {
            return new String(data, "UTF8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Type readTypeValue() {
        return new Type(readType());
    }

    private Object readAnyValue() {
        TypeDescription type = readType();
        switch (type.getTypeClass().getValue()) {
        case TypeClass.VOID_value:
            return Any.VOID;

        case TypeClass.BOOLEAN_value:
            return readBooleanValue();

        case TypeClass.BYTE_value:
            return readByteValue();

        case TypeClass.SHORT_value:
            return readShortValue();

        case TypeClass.UNSIGNED_SHORT_value:
            return new Any(Type.UNSIGNED_SHORT, readShortValue());

        case TypeClass.LONG_value:
            return readLongValue();

        case TypeClass.UNSIGNED_LONG_value:
            return new Any(Type.UNSIGNED_LONG, readLongValue());

        case TypeClass.HYPER_value:
            return readHyperValue();

        case TypeClass.UNSIGNED_HYPER_value:
            return new Any(Type.UNSIGNED_HYPER, readHyperValue());

        case TypeClass.FLOAT_value:
            return readFloatValue();

        case TypeClass.DOUBLE_value:
            return readDoubleValue();

        case TypeClass.CHAR_value:
            return readCharValue();

        case TypeClass.STRING_value:
            return readStringValue();

        case TypeClass.TYPE_value:
            return readTypeValue();

        case TypeClass.SEQUENCE_value:
            {
                Object value = readSequenceValue(type);
                TypeDescription ctype = (TypeDescription)
                    type.getComponentType();
                while (ctype.getTypeClass() == TypeClass.SEQUENCE) {
                    ctype = (TypeDescription) ctype.getComponentType();
                }
                switch (ctype.getTypeClass().getValue()) {
                case TypeClass.UNSIGNED_SHORT_value:
                case TypeClass.UNSIGNED_LONG_value:
                case TypeClass.UNSIGNED_HYPER_value:
                    return new Any(new Type(type), value);

                case TypeClass.STRUCT_value:
                    if (ctype.hasTypeArguments()) {
                        return new Any(new Type(type), value);
                    }
                default:
                    return value;
                }
            }

        case TypeClass.ENUM_value:
            return readEnumValue(type);

        case TypeClass.STRUCT_value:
            {
                Object value = readStructValue(type);
                return type.hasTypeArguments()
                    ? new Any(new Type(type), value) : value;
            }

        case TypeClass.EXCEPTION_value:
            return readExceptionValue(type);

        case TypeClass.INTERFACE_value:
            {
                Object value = readInterfaceValue(type);
                return type.getZClass() == XInterface.class
                    ? value : new Any(new Type(type), value);
            }

        default:
            throw new RuntimeException(
                "Reading ANY with bad type " + type.getTypeClass());
        }
    }

    private Object readSequenceValue(TypeDescription type) {
        int len = readCompressedNumber();
        TypeDescription ctype = (TypeDescription) type.getComponentType();
        if (ctype.getTypeClass() == TypeClass.BYTE) {
            byte[] data = new byte[len];
            readBytes(data);
            return data;
        } else {
            Object value = Array.newInstance(
                ctype.getTypeClass() == TypeClass.ANY
                ? Object.class : ctype.getZClass(), len);
            for (int i = 0; i < len; ++i) {
                Array.set(value, i, readValue(ctype));
            }
            return value;
        }
    }

    private Enum readEnumValue(TypeDescription type) {
        try {
            return (Enum)
                type.getZClass().getMethod(
                    "fromInt", new Class[] { int.class }).
                invoke(null, new Object[] { readLongValue() });
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e.toString());
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e.toString());
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private Object readStructValue(TypeDescription type) {
        Object value;
        try {
            value = type.getZClass().newInstance();
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e.toString());
        } catch (InstantiationException e) {
            throw new RuntimeException(e.toString());
        }
        readFields(type, value);
        return value;
    }

    private Exception readExceptionValue(TypeDescription type) {
        Exception value;
        try {
            value = (Exception)
                type.getZClass().getConstructor(new Class[] { String.class }).
                newInstance(new Object[] { readStringValue() });
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e.toString());
        } catch (InstantiationException e) {
            throw new RuntimeException(e.toString());
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e.toString());
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e.toString());
        }
        readFields(type, value);
        return value;
    }

    private Object readInterfaceValue(TypeDescription type) {
        return readInterface(new Type(type));
    }

    private int readCompressedNumber() {
        int number = read8Bit();
        try {
            return number < 0xFF ? number : input.readInt();
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private void readBytes(byte[] data) {
        try {
            input.readFully(data);
        } catch (IOException e) {
            throw new RuntimeException(e.toString());
        }
    }

    private void readFields(TypeDescription type, Object value) {
        IFieldDescription[] fields = type.getFieldDescriptions();
        for (int i = 0; i < fields.length; ++i) {
            try {
                fields[i].getField().set(
                    value,
                    readValue(
                        (TypeDescription) fields[i].getTypeDescription()));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e.toString());
            }
        }
    }

    private final IBridge bridge;
    private final String[] objectIdCache;
    private final ThreadId[] threadIdCache;
    private final TypeDescription[] typeCache;
    private DataInputStream input;
}
