/*
 * 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.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Date;
import java.util.UUID;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.internal.binary.streams.BinaryByteBufferInputStream;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.binary.BinaryObject;
import org.apache.ignite.binary.BinaryField;

import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * Implementation of binary field descriptor.
 */
public class BinaryFieldImpl implements BinaryFieldEx {
    /** Binary context that created this field. */
    private final BinaryContext ctx;

    /** Type ID. */
    private final int typeId;

    /** Well-known object schemas. */
    @GridToStringExclude
    private final BinarySchemaRegistry schemas;

    /** Field name. */
    private final String fieldName;

    /** Pre-calculated field ID. */
    private final int fieldId;

    /**
     * Constructor.
     *
     * @param ctx Binary context.
     * @param typeId Type ID.
     * @param schemas Schemas.
     * @param fieldName Field name.
     * @param fieldId Field ID.
     */
    public BinaryFieldImpl(
        BinaryContext ctx,
        int typeId,
        BinarySchemaRegistry schemas,
        String fieldName,
        int fieldId
    ) {
        assert ctx != null;
        assert typeId != 0;
        assert schemas != null;
        assert fieldId != 0;

        this.ctx = ctx;
        this.typeId = typeId;
        this.schemas = schemas;
        this.fieldName = fieldName;
        this.fieldId = fieldId;
    }

    /** {@inheritDoc} */
    @Override public String name() {
        return fieldName;
    }

    /**
     * @return Field ID.
     */
    public int fieldId() {
        return fieldId;
    }

    /** {@inheritDoc} */
    @Override public boolean exists(BinaryObject obj) {
        BinaryObjectExImpl obj0 = (BinaryObjectExImpl)obj;

        return fieldOrder(obj0) != BinarySchema.ORDER_NOT_FOUND;
    }

    /** {@inheritDoc} */
    @SuppressWarnings("unchecked")
    @Override public <T> T value(BinaryObject obj) {
        BinaryObjectExImpl obj0 = (BinaryObjectExImpl)obj;

        int order = fieldOrder(obj0);

        return order != BinarySchema.ORDER_NOT_FOUND ? (T)obj0.fieldByOrder(order) : null;
    }

    /** {@inheritDoc} */
    @Override public int typeId() {
        return typeId;
    }

    /** {@inheritDoc} */
    @Override public boolean writeField(BinaryObject obj, ByteBuffer buf) {
        BinaryObjectExImpl obj0 = (BinaryObjectExImpl)obj;

        int order = fieldOrder(obj0);

        return obj0.writeFieldByOrder(order, buf);
    }

    /** {@inheritDoc} */
    @Override public <F> F readField(ByteBuffer buf) {
        ByteOrder oldOrder = buf.order();

        try {
            buf.order(ByteOrder.LITTLE_ENDIAN);

            int pos = buf.position();

            byte hdr = buf.get();

            Object val;

            switch (hdr) {
                case GridBinaryMarshaller.INT:
                    val = buf.getInt();

                    break;

                case GridBinaryMarshaller.LONG:
                    val = buf.getLong();

                    break;

                case GridBinaryMarshaller.BOOLEAN:
                    val = buf.get() != 0;

                    break;

                case GridBinaryMarshaller.SHORT:
                    val = buf.getShort();

                    break;

                case GridBinaryMarshaller.BYTE:
                    val = buf.get();

                    break;

                case GridBinaryMarshaller.CHAR:
                    val = buf.getChar();

                    break;

                case GridBinaryMarshaller.FLOAT:
                    val = buf.getFloat();

                    break;

                case GridBinaryMarshaller.DOUBLE:
                    val = buf.getDouble();

                    break;

                case GridBinaryMarshaller.STRING: {
                    int dataLen = buf.getInt();

                    byte[] data = new byte[dataLen];

                    buf.get(data);

                    val = new String(data, 0, dataLen, UTF_8);

                    break;
                }

                case GridBinaryMarshaller.DATE: {
                    long time = buf.getLong();

                    val = new Date(time);

                    break;
                }

                case GridBinaryMarshaller.TIMESTAMP: {
                    long time = buf.getLong();
                    int nanos = buf.getInt();

                    Timestamp ts = new Timestamp(time);

                    ts.setNanos(ts.getNanos() + nanos);

                    val = ts;

                    break;
                }

                case GridBinaryMarshaller.TIME: {
                    long time = buf.getLong();

                    val = new Time(time);

                    break;
                }

                case GridBinaryMarshaller.UUID: {
                    long most = buf.getLong();
                    long least = buf.getLong();

                    val = new UUID(most, least);

                    break;
                }

                case GridBinaryMarshaller.DECIMAL: {
                    int scale = buf.getInt();

                    int dataLen = buf.getInt();

                    byte[] data = new byte[dataLen];

                    buf.get(data);

                    boolean negative = data[0] < 0;

                    if (negative)
                        data[0] &= 0x7F;

                    BigInteger intVal = new BigInteger(data);

                    if (negative)
                        intVal = intVal.negate();

                    val = new BigDecimal(intVal, scale);

                    break;
                }

                case GridBinaryMarshaller.NULL:
                    val = null;

                    break;

                default:
                    // Restore buffer position.
                    buf.position(pos);

                    val = BinaryUtils.unmarshal(BinaryByteBufferInputStream.create(buf), ctx, null);

                    break;
            }

            return (F)val;
        }
        finally {
            buf.order(oldOrder);
        }
    }

    /**
     * Get relative field offset.
     *
     * @param obj Object.
     * @return Field offset.
     */
    public int fieldOrder(BinaryObjectExImpl obj) {
        if (typeId != obj.typeId()) {
            throw new BinaryObjectException("Failed to get field because type ID of passed object differs" +
                " from type ID this " + BinaryField.class.getSimpleName() + " belongs to [expected=" + typeId +
                ", actual=" + obj.typeId() + ']');
        }

        int schemaId = obj.schemaId();

        if (schemaId == 0)
            return BinarySchema.ORDER_NOT_FOUND;

        BinarySchema schema = schemas.schema(schemaId);

        if (schema == null) {
            schema = obj.createSchema();

            schemas.addSchema(schemaId, schema);
        }

        assert schema != null;

        return schema.order(fieldId);
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(BinaryFieldImpl.class, this);
    }
}
