/*
 * 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.ignite.internal.binary;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.UnregisteredBinaryTypeException;
import org.apache.ignite.internal.UnregisteredClassException;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;

/**
 * Field accessor to speedup access.
 */
public abstract class BinaryFieldAccessor {
    /** Field ID. */
    protected final int id;

    /** Field name */
    protected final String name;

    /** Mode. */
    protected final BinaryWriteMode mode;

    /**
     * Create accessor for the field.
     *
     * @param field Field.
     * @param id FIeld ID.
     * @return Accessor.
     */
    public static BinaryFieldAccessor create(Field field, int id) {
        BinaryWriteMode mode = BinaryUtils.mode(field.getType());

        switch (mode) {
            case P_BYTE:
                return new BytePrimitiveAccessor(field, id);

            case P_BOOLEAN:
                return new BooleanPrimitiveAccessor(field, id);

            case P_SHORT:
                return new ShortPrimitiveAccessor(field, id);

            case P_CHAR:
                return new CharPrimitiveAccessor(field, id);

            case P_INT:
                return new IntPrimitiveAccessor(field, id);

            case P_LONG:
                return new LongPrimitiveAccessor(field, id);

            case P_FLOAT:
                return new FloatPrimitiveAccessor(field, id);

            case P_DOUBLE:
                return new DoublePrimitiveAccessor(field, id);

            case BYTE:
            case BOOLEAN:
            case SHORT:
            case CHAR:
            case INT:
            case LONG:
            case FLOAT:
            case DOUBLE:
            case DECIMAL:
            case STRING:
            case UUID:
            case DATE:
            case TIMESTAMP:
            case TIME:
            case BYTE_ARR:
            case SHORT_ARR:
            case INT_ARR:
            case LONG_ARR:
            case FLOAT_ARR:
            case DOUBLE_ARR:
            case CHAR_ARR:
            case BOOLEAN_ARR:
            case DECIMAL_ARR:
            case STRING_ARR:
            case UUID_ARR:
            case DATE_ARR:
            case TIMESTAMP_ARR:
            case TIME_ARR:
            case ENUM_ARR:
            case OBJECT_ARR:
            case BINARY_OBJ:
            case BINARY:
                return new DefaultFinalClassAccessor(field, id, mode, false);

            default:
                return new DefaultFinalClassAccessor(field, id, mode, !U.isFinal(field.getType()));
        }
    }

    /**
     * Protected constructor.
     *
     * @param id Field ID.
     * @param mode Mode;
     */
    protected BinaryFieldAccessor(Field field, int id, BinaryWriteMode mode) {
        assert field != null;
        assert id != 0;
        assert mode != null;

        this.name = field.getName();
        this.id = id;
        this.mode = mode;
    }

    /**
     * Get mode.
     *
     * @return Mode.
     */
    public BinaryWriteMode mode() {
        return mode;
    }

    /**
     * Write field.
     *
     * @param obj Object.
     * @param writer Writer.
     * @throws BinaryObjectException If failed.
     */
    public void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
        try {
            write0(obj, writer);
        }
        catch (Exception ex) {
            if (ex instanceof UnregisteredClassException || ex instanceof UnregisteredBinaryTypeException)
                throw ex;

            if (S.INCLUDE_SENSITIVE && !F.isEmpty(name))
                throw new BinaryObjectException("Failed to write field [name=" + name + ']', ex);
            else
                throw new BinaryObjectException("Failed to write field [id=" + id + ']', ex);
        }
    }

    /**
     * Write field.
     *
     * @param obj Object.
     * @param writer Writer.
     * @throws BinaryObjectException If failed.
     */
    protected abstract void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException;

    /**
     * Read field.
     *
     * @param obj Object.
     * @param reader Reader.
     * @throws BinaryObjectException If failed.
     */
    public void read(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
        try {
            read0(obj, reader);
        }
        catch (Exception ex) {
            if (S.INCLUDE_SENSITIVE && !F.isEmpty(name))
                throw new BinaryObjectException("Failed to read field [name=" + name + ']', ex);
            else
                throw new BinaryObjectException("Failed to read field [id=" + id + ']', ex);
        }
    }

    /**
     * Read field.
     *
     * @param obj Object.
     * @param reader Reader.
     * @throws BinaryObjectException If failed.
     */
    protected abstract void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException;

    /**
     * Base primitive field accessor.
     */
    private static abstract class AbstractPrimitiveAccessor extends BinaryFieldAccessor {
        /** Offset. */
        protected final long offset;

        /**
         * Constructor.
         *
         * @param field Field.
         * @param id Field ID.
         * @param mode Mode.
         */
        protected AbstractPrimitiveAccessor(Field field, int id, BinaryWriteMode mode) {
            super(field, id, mode);

            offset = GridUnsafe.objectFieldOffset(field);
        }
    }

    /**
     * Byte field accessor.
     */
    private static class BytePrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public BytePrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_BYTE);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            byte val = GridUnsafe.getByteField(obj, offset);

            writer.writeByteFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            byte val = reader.readByte(id);

            GridUnsafe.putByteField(obj, offset, val);
        }
    }

    /**
     * Boolean field accessor.
     */
    private static class BooleanPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public BooleanPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_BOOLEAN);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            boolean val = GridUnsafe.getBooleanField(obj, offset);

            writer.writeBooleanFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            boolean val = reader.readBoolean(id);

            GridUnsafe.putBooleanField(obj, offset, val);
        }
    }

    /**
     * Short field accessor.
     */
    private static class ShortPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public ShortPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_SHORT);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            short val = GridUnsafe.getShortField(obj, offset);

            writer.writeShortFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            short val = reader.readShort(id);

            GridUnsafe.putShortField(obj, offset, val);
        }
    }

    /**
     * Char field accessor.
     */
    private static class CharPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public CharPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_CHAR);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            char val = GridUnsafe.getCharField(obj, offset);

            writer.writeCharFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            char val = reader.readChar(id);

            GridUnsafe.putCharField(obj, offset, val);
        }
    }

    /**
     * Int field accessor.
     */
    private static class IntPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public IntPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_INT);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            int val = GridUnsafe.getIntField(obj, offset);

            writer.writeIntFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            int val = reader.readInt(id);

            GridUnsafe.putIntField(obj, offset, val);
        }
    }

    /**
     * Long field accessor.
     */
    private static class LongPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public LongPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_LONG);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            long val = GridUnsafe.getLongField(obj, offset);

            writer.writeLongFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            long val = reader.readLong(id);

            GridUnsafe.putLongField(obj, offset, val);
        }
    }

    /**
     * Float field accessor.
     */
    private static class FloatPrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public FloatPrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_FLOAT);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            float val = GridUnsafe.getFloatField(obj, offset);

            writer.writeFloatFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            float val = reader.readFloat(id);

            GridUnsafe.putFloatField(obj, offset, val);
        }
    }

    /**
     * Double field accessor.
     */
    private static class DoublePrimitiveAccessor extends AbstractPrimitiveAccessor {
        /**
         * Constructor.
         *
         * @param field Field.
         */
        public DoublePrimitiveAccessor(Field field, int id) {
            super(field, id, BinaryWriteMode.P_DOUBLE);
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            writer.writeFieldIdNoSchemaUpdate(id);

            double val = GridUnsafe.getDoubleField(obj, offset);

            writer.writeDoubleFieldPrimitive(val);
        }

        /** {@inheritDoc} */
        @Override protected void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            double val = reader.readDouble(id);

            GridUnsafe.putDoubleField(obj, offset, val);
        }
    }

    /**
     * Default accessor.
     */
    private static class DefaultFinalClassAccessor extends BinaryFieldAccessor {
        /** Target field. */
        private final Field field;

        /** Dynamic accessor flag. */
        private final boolean dynamic;

        /**
         * Constructor.
         *
         * @param field Field.
         * @param id Field ID.
         * @param mode Mode.
         */
        DefaultFinalClassAccessor(Field field, int id, BinaryWriteMode mode, boolean dynamic) {
            super(field, id, mode);

            this.field = field;
            this.dynamic = dynamic;
        }

        /** {@inheritDoc} */
        @Override protected void write0(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
            assert obj != null;
            assert writer != null;

            writer.writeFieldIdNoSchemaUpdate(id);

            Object val;

            try {
                val = field.get(obj);
            }
            catch (IllegalAccessException e) {
                throw new BinaryObjectException("Failed to get value for field: " + field, e);
            }

            switch (mode(val)) {
                case BYTE:
                    writer.writeByteField((Byte)val);

                    break;

                case SHORT:
                    writer.writeShortField((Short)val);

                    break;

                case INT:
                    writer.writeIntField((Integer)val);

                    break;

                case LONG:
                    writer.writeLongField((Long)val);

                    break;

                case FLOAT:
                    writer.writeFloatField((Float)val);

                    break;

                case DOUBLE:
                    writer.writeDoubleField((Double)val);

                    break;

                case CHAR:
                    writer.writeCharField((Character)val);

                    break;

                case BOOLEAN:
                    writer.writeBooleanField((Boolean)val);

                    break;

                case DECIMAL:
                    writer.writeDecimalField((BigDecimal)val);

                    break;

                case STRING:
                    writer.writeStringField((String)val);

                    break;

                case UUID:
                    writer.writeUuidField((UUID)val);

                    break;

                case DATE:
                    writer.writeDateField((Date)val);

                    break;

                case TIMESTAMP:
                    writer.writeTimestampField((Timestamp)val);

                    break;

                case TIME:
                    writer.writeTimeField((Time)val);

                    break;

                case BYTE_ARR:
                    writer.writeByteArrayField((byte[])val);

                    break;

                case SHORT_ARR:
                    writer.writeShortArrayField((short[])val);

                    break;

                case INT_ARR:
                    writer.writeIntArrayField((int[])val);

                    break;

                case LONG_ARR:
                    writer.writeLongArrayField((long[])val);

                    break;

                case FLOAT_ARR:
                    writer.writeFloatArrayField((float[])val);

                    break;

                case DOUBLE_ARR:
                    writer.writeDoubleArrayField((double[])val);

                    break;

                case CHAR_ARR:
                    writer.writeCharArrayField((char[])val);

                    break;

                case BOOLEAN_ARR:
                    writer.writeBooleanArrayField((boolean[])val);

                    break;

                case DECIMAL_ARR:
                    writer.writeDecimalArrayField((BigDecimal[])val);

                    break;

                case STRING_ARR:
                    writer.writeStringArrayField((String[])val);

                    break;

                case UUID_ARR:
                    writer.writeUuidArrayField((UUID[])val);

                    break;

                case DATE_ARR:
                    writer.writeDateArrayField((Date[])val);

                    break;

                case TIMESTAMP_ARR:
                    writer.writeTimestampArrayField((Timestamp[])val);

                    break;

                case TIME_ARR:
                    writer.writeTimeArrayField((Time[])val);

                    break;

                case OBJECT_ARR:
                    writer.writeObjectArrayField((Object[])val);

                    break;

                case COL:
                    writer.writeCollectionField((Collection<?>)val);

                    break;

                case MAP:
                    writer.writeMapField((Map<?, ?>)val);

                    break;

                case BINARY_OBJ:
                    writer.writeBinaryObjectField((BinaryObjectImpl)val);

                    break;

                case ENUM:
                    writer.writeEnumField((Enum<?>)val);

                    break;

                case BINARY_ENUM:
                    writer.doWriteBinaryEnum((BinaryEnumObjectImpl)val);

                    break;

                case ENUM_ARR:
                    writer.writeEnumArrayField((Object[])val);

                    break;

                case BINARY:
                case OBJECT:
                case PROXY:
                    writer.writeObjectField(val);

                    break;

                case CLASS:
                    writer.writeClassField((Class)val);

                    break;

                default:
                    assert false : "Invalid mode: " + mode;
            }
        }

        /** {@inheritDoc} */
        @Override public void read0(Object obj, BinaryReaderExImpl reader) throws BinaryObjectException {
            Object val = dynamic ? reader.readField(id) : readFixedType(reader);

            try {
                if (val != null || !field.getType().isPrimitive())
                    field.set(obj, val);
            }
            catch (IllegalAccessException e) {
                throw new BinaryObjectException("Failed to set value for field: " + field, e);
            }
        }

        /**
         * Reads fixed type from the given reader with flags validation.
         *
         * @param reader Reader to read from.
         * @return Read value.
         * @throws BinaryObjectException If failed to read value from the stream.
         */
        protected Object readFixedType(BinaryReaderExImpl reader) throws BinaryObjectException {
            Object val = null;

            switch (mode) {
                case BYTE:
                    val = reader.readByteNullable(id);

                    break;

                case SHORT:
                    val = reader.readShortNullable(id);

                    break;

                case INT:
                    val = reader.readIntNullable(id);

                    break;

                case LONG:
                    val = reader.readLongNullable(id);

                    break;

                case FLOAT:
                    val = reader.readFloatNullable(id);

                    break;

                case DOUBLE:
                    val = reader.readDoubleNullable(id);

                    break;

                case CHAR:
                    val = reader.readCharNullable(id);

                    break;

                case BOOLEAN:
                    val = reader.readBooleanNullable(id);

                    break;

                case DECIMAL:
                    val = reader.readDecimal(id);

                    break;

                case STRING:
                    val = reader.readString(id);

                    break;

                case UUID:
                    val = reader.readUuid(id);

                    break;

                case DATE:
                    val = reader.readDate(id);

                    break;

                case TIMESTAMP:
                    val = reader.readTimestamp(id);

                    break;

                case TIME:
                    val = reader.readTime(id);

                    break;

                case BYTE_ARR:
                    val = reader.readByteArray(id);

                    break;

                case SHORT_ARR:
                    val = reader.readShortArray(id);

                    break;

                case INT_ARR:
                    val = reader.readIntArray(id);

                    break;

                case LONG_ARR:
                    val = reader.readLongArray(id);

                    break;

                case FLOAT_ARR:
                    val = reader.readFloatArray(id);

                    break;

                case DOUBLE_ARR:
                    val = reader.readDoubleArray(id);

                    break;

                case CHAR_ARR:
                    val = reader.readCharArray(id);

                    break;

                case BOOLEAN_ARR:
                    val = reader.readBooleanArray(id);

                    break;

                case DECIMAL_ARR:
                    val = reader.readDecimalArray(id);

                    break;

                case STRING_ARR:
                    val = reader.readStringArray(id);

                    break;

                case UUID_ARR:
                    val = reader.readUuidArray(id);

                    break;

                case DATE_ARR:
                    val = reader.readDateArray(id);

                    break;

                case TIMESTAMP_ARR:
                    val = reader.readTimestampArray(id);

                    break;

                case TIME_ARR:
                    val = reader.readTimeArray(id);

                    break;

                case OBJECT_ARR:
                    val = reader.readObjectArray(id);

                    break;

                case COL:
                    val = reader.readCollection(id, null);

                    break;

                case MAP:
                    val = reader.readMap(id, null);

                    break;

                case BINARY_OBJ:
                    val = reader.readBinaryObject(id);

                    break;

                case ENUM:
                    val = reader.readEnum(id, field.getType());

                    break;

                case ENUM_ARR:
                    val = reader.readEnumArray(id, field.getType().getComponentType());

                    break;

                case BINARY_ENUM:
                    val = reader.readBinaryEnum(id);

                    break;

                case BINARY:
                case OBJECT:
                    val = reader.readObject(id);

                    break;

                case CLASS:
                    val = reader.readClass(id);

                    break;

                default:
                    assert false : "Invalid mode: " + mode;
            }

            return val;
        }

        /**
         * @param val Val to get write mode for.
         * @return Write mode.
         */
        protected BinaryWriteMode mode(Object val) {
            return dynamic ?
                val == null ? BinaryWriteMode.OBJECT : BinaryUtils.mode(val.getClass()) :
                mode;
        }
    }
}
