/*
 * 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.cassandra.cql3.functions.types;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.*;

import com.google.common.reflect.TypeToken;

import org.apache.cassandra.transport.ProtocolVersion;
import org.apache.cassandra.cql3.functions.types.exceptions.InvalidTypeException;

abstract class AbstractGettableByIndexData implements GettableByIndexData
{

    protected final ProtocolVersion protocolVersion;

    AbstractGettableByIndexData(ProtocolVersion protocolVersion)
    {
        this.protocolVersion = protocolVersion;
    }

    /**
     * Returns the type for the value at index {@code i}.
     *
     * @param i the index of the type to fetch.
     * @return the type of the value at index {@code i}.
     * @throws IndexOutOfBoundsException if {@code i} is not a valid index.
     */
    protected abstract DataType getType(int i);

    /**
     * Returns the name corresponding to the value at index {@code i}.
     *
     * @param i the index of the name to fetch.
     * @return the name corresponding to the value at index {@code i}.
     * @throws IndexOutOfBoundsException if {@code i} is not a valid index.
     */
    protected abstract String getName(int i);

    /**
     * Returns the value at index {@code i}.
     *
     * @param i the index to fetch.
     * @return the value at index {@code i}.
     * @throws IndexOutOfBoundsException if {@code i} is not a valid index.
     */
    protected abstract ByteBuffer getValue(int i);

    protected abstract CodecRegistry getCodecRegistry();

    protected <T> TypeCodec<T> codecFor(int i)
    {
        return getCodecRegistry().codecFor(getType(i));
    }

    protected <T> TypeCodec<T> codecFor(int i, Class<T> javaClass)
    {
        return getCodecRegistry().codecFor(getType(i), javaClass);
    }

    protected <T> TypeCodec<T> codecFor(int i, TypeToken<T> javaType)
    {
        return getCodecRegistry().codecFor(getType(i), javaType);
    }

    protected <T> TypeCodec<T> codecFor(int i, T value)
    {
        return getCodecRegistry().codecFor(getType(i), value);
    }

    void checkType(int i, DataType.Name actual)
    {
        DataType.Name expected = getType(i).getName();
        if (!actual.isCompatibleWith(expected))
            throw new InvalidTypeException(
            String.format("Value %s is of type %s, not %s", getName(i), expected, actual));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isNull(int i)
    {
        return getValue(i) == null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean getBool(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Boolean> codec = codecFor(i, Boolean.class);
        if (codec instanceof TypeCodec.PrimitiveBooleanCodec)
            return ((TypeCodec.PrimitiveBooleanCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public byte getByte(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Byte> codec = codecFor(i, Byte.class);
        if (codec instanceof TypeCodec.PrimitiveByteCodec)
            return ((TypeCodec.PrimitiveByteCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public short getShort(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Short> codec = codecFor(i, Short.class);
        if (codec instanceof TypeCodec.PrimitiveShortCodec)
            return ((TypeCodec.PrimitiveShortCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getInt(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Integer> codec = codecFor(i, Integer.class);
        if (codec instanceof TypeCodec.PrimitiveIntCodec)
            return ((TypeCodec.PrimitiveIntCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long getLong(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Long> codec = codecFor(i, Long.class);
        if (codec instanceof TypeCodec.PrimitiveLongCodec)
            return ((TypeCodec.PrimitiveLongCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Date getTimestamp(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, Date.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LocalDate getDate(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, LocalDate.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long getTime(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Long> codec = codecFor(i, Long.class);
        if (codec instanceof TypeCodec.PrimitiveLongCodec)
            return ((TypeCodec.PrimitiveLongCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public float getFloat(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Float> codec = codecFor(i, Float.class);
        if (codec instanceof TypeCodec.PrimitiveFloatCodec)
            return ((TypeCodec.PrimitiveFloatCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public double getDouble(int i)
    {
        ByteBuffer value = getValue(i);
        TypeCodec<Double> codec = codecFor(i, Double.class);
        if (codec instanceof TypeCodec.PrimitiveDoubleCodec)
            return ((TypeCodec.PrimitiveDoubleCodec) codec).deserializeNoBoxing(value, protocolVersion);
        else return codec.deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ByteBuffer getBytesUnsafe(int i)
    {
        ByteBuffer value = getValue(i);
        if (value == null) return null;
        return value.duplicate();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ByteBuffer getBytes(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, ByteBuffer.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getString(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, String.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigInteger getVarint(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, BigInteger.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public BigDecimal getDecimal(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, BigDecimal.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public UUID getUUID(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, UUID.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public InetAddress getInet(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, InetAddress.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> List<T> getList(int i, Class<T> elementsClass)
    {
        return getList(i, TypeToken.of(elementsClass));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> List<T> getList(int i, TypeToken<T> elementsType)
    {
        ByteBuffer value = getValue(i);
        TypeToken<List<T>> javaType = TypeTokens.listOf(elementsType);
        return codecFor(i, javaType).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> Set<T> getSet(int i, Class<T> elementsClass)
    {
        return getSet(i, TypeToken.of(elementsClass));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <T> Set<T> getSet(int i, TypeToken<T> elementsType)
    {
        ByteBuffer value = getValue(i);
        TypeToken<Set<T>> javaType = TypeTokens.setOf(elementsType);
        return codecFor(i, javaType).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <K, V> Map<K, V> getMap(int i, Class<K> keysClass, Class<V> valuesClass)
    {
        return getMap(i, TypeToken.of(keysClass), TypeToken.of(valuesClass));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public <K, V> Map<K, V> getMap(int i, TypeToken<K> keysType, TypeToken<V> valuesType)
    {
        ByteBuffer value = getValue(i);
        TypeToken<Map<K, V>> javaType = TypeTokens.mapOf(keysType, valuesType);
        return codecFor(i, javaType).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public UDTValue getUDTValue(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, UDTValue.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @SuppressWarnings("unchecked")
    public TupleValue getTupleValue(int i)
    {
        ByteBuffer value = getValue(i);
        return codecFor(i, TupleValue.class).deserialize(value, protocolVersion);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Object getObject(int i)
    {
        return get(i, codecFor(i));
    }

    @Override
    public <T> T get(int i, Class<T> targetClass)
    {
        return get(i, codecFor(i, targetClass));
    }

    @Override
    public <T> T get(int i, TypeToken<T> targetType)
    {
        return get(i, codecFor(i, targetType));
    }

    @Override
    public <T> T get(int i, TypeCodec<T> codec)
    {
        checkType(i, codec.getCqlType().getName());
        ByteBuffer value = getValue(i);
        return codec.deserialize(value, protocolVersion);
    }
}
