/*
 * 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.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;

import com.google.common.cache.*;
import com.google.common.reflect.TypeToken;
import com.google.common.util.concurrent.UncheckedExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.cassandra.cql3.functions.types.exceptions.CodecNotFoundException;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.apache.cassandra.cql3.functions.types.DataType.Name.*;

/**
 * A registry for {@link TypeCodec}s. When the driver needs to serialize or deserialize a Java type
 * to/from CQL, it will lookup in the registry for a suitable codec. The registry is initialized
 * with default codecs that handle basic conversions (e.g. CQL {@code text} to {@code
 * java.lang.String}), and users can add their own. Complex codecs can also be generated on-the-fly
 * from simpler ones (more details below).
 *
 * <h3>Creating a registry </h3>
 * <p>
 * By default, the driver uses {@code CodecRegistry#DEFAULT_INSTANCE}, a shareable, JVM-wide
 * instance initialized with built-in codecs for all the base CQL types. The only reason to create
 * your own instances is if you have multiple {@code Cluster} objects that use different sets of
 * codecs. In that case, use {@code
 * Cluster.Builder#withCodecRegistry(CodecRegistry)} to associate the
 * registry with the cluster:
 *
 * <pre>{@code
 * CodecRegistry myCodecRegistry = new CodecRegistry();
 * myCodecRegistry.register(myCodec1, myCodec2, myCodec3);
 * Cluster cluster = Cluster.builder().withCodecRegistry(myCodecRegistry).build();
 *
 * // To retrieve the registry later:
 * CodecRegistry registry = cluster.getConfiguration().getCodecRegistry();
 * }</pre>
 * <p>
 * {@code CodecRegistry} instances are thread-safe.
 *
 * <p>It is possible to turn on log messages by setting the {@code
 * CodecRegistry} logger level to {@code TRACE}. Beware that the registry
 * can be very verbose at this log level.
 *
 * <h3>Registering and using custom codecs </h3>
 * <p>
 * To create a custom codec, write a class that extends {@link TypeCodec}, create an instance, and
 * pass it to one of the {@link #register(TypeCodec) register} methods; for example, one could
 * create a codec that maps CQL timestamps to JDK8's {@code java.time.LocalDate}:
 *
 * <pre>{@code
 * class LocalDateCodec extends TypeCodec<java.time.LocalDate> {
 *    ...
 * }
 * myCodecRegistry.register(new LocalDateCodec());
 * }</pre>
 * <p>
 * The conversion will be available to:
 *
 * <ul>
 * <li>all driver types that implement {@link GettableByIndexData}, {@link GettableByNameData},
 * {@link SettableByIndexData} and/or {@link SettableByNameData}. Namely: {@code Row}, {@code
 * BoundStatement}, {@link UDTValue} and {@link TupleValue};
 * <li>{@code SimpleStatement#SimpleStatement(String, Object...) simple statements};
 * <li>statements created with the {@code querybuilder.QueryBuilder Query
 * builder}.
 * </ul>
 *
 * <p>Example:
 *
 * <pre>{@code
 * Row row = session.executeQuery("select date from some_table where pk = 1").one();
 * java.time.LocalDate date = row.get(0, java.time.LocalDate.class); // uses LocalDateCodec registered above
 * }</pre>
 * <p>
 * You can also bypass the codec registry by passing a standalone codec instance to methods such as
 * {@link GettableByIndexData#get(int, TypeCodec)}.
 *
 * <h3>Codec generation </h3>
 * <p>
 * When a {@code CodecRegistry} cannot find a suitable codec among existing ones, it will attempt to
 * create it on-the-fly. It can manage:
 *
 * <ul>
 * <li>collections (lists, sets and maps) of known types. For example, if you registered a codec
 * for JDK8's {@code java.time.LocalDate} like in the example above, you get {@code
 * List<LocalDate>>} and {@code Set<LocalDate>>} handled for free, as well as all {@code Map}
 * types whose keys and/or values are {@code java.time.LocalDate}. This works recursively for
 * nested collections;
 * <li>{@link UserType user types}, mapped to {@link UDTValue} objects. Custom codecs are
 * available recursively to the UDT's fields, so if one of your fields is a {@code timestamp}
 * you can use your {@code LocalDateCodec} to retrieve it as a {@code java.time.LocalDate};
 * <li>{@link TupleType tuple types}, mapped to {@link TupleValue} (with the same rules for nested
 * fields);
 * <li>{@link DataType.CustomType custom types}, mapped to {@code
 * ByteBuffer}.
 * </ul>
 * <p>
 * If the codec registry encounters a mapping that it can't handle automatically, a {@link
 * CodecNotFoundException} is thrown; you'll need to register a custom codec for it.
 *
 * <h3>Performance and caching </h3>
 * <p>
 * Whenever possible, the registry will cache the result of a codec lookup for a specific type
 * mapping, including any generated codec. For example, if you registered {@code LocalDateCodec} and
 * ask the registry for a codec to convert a CQL {@code list<timestamp>} to a Java {@code
 * List<LocalDate>}:
 *
 * <ol>
 * <li>the first lookup will generate a {@code TypeCodec<List<LocalDate>>} from {@code
 * LocalDateCodec}, and put it in the cache;
 * <li>the second lookup will hit the cache directly, and reuse the previously generated instance.
 * </ol>
 * <p>
 * The javadoc for each {@link #codecFor(DataType) codecFor} variant specifies whether the result
 * can be cached or not.
 *
 * <h3>Codec order </h3>
 * <p>
 * When the registry looks up a codec, the rules of precedence are:
 *
 * <ul>
 * <li>if a result was previously cached for that mapping, it is returned;
 * <li>otherwise, the registry checks the list of built-in codecs – the default ones – and the
 * ones that were explicitly registered (in the order that they were registered). It calls
 * each codec's {@code accepts} methods to determine if it can handle the mapping, and if so
 * returns it;
 * <li>otherwise, the registry tries to generate a codec, according to the rules outlined above.
 * </ul>
 * <p>
 * It is currently impossible to override an existing codec. If you try to do so, {@link
 * #register(TypeCodec)} will log a warning and ignore it.
 */
public final class CodecRegistry
{

    private static final Logger logger = LoggerFactory.getLogger(CodecRegistry.class);

    private static final Map<DataType.Name, TypeCodec<?>> BUILT_IN_CODECS_MAP =
    new EnumMap<>(DataType.Name.class);

    static
    {
        BUILT_IN_CODECS_MAP.put(DataType.Name.ASCII, TypeCodec.ascii());
        BUILT_IN_CODECS_MAP.put(DataType.Name.BIGINT, TypeCodec.bigint());
        BUILT_IN_CODECS_MAP.put(DataType.Name.BLOB, TypeCodec.blob());
        BUILT_IN_CODECS_MAP.put(DataType.Name.BOOLEAN, TypeCodec.cboolean());
        BUILT_IN_CODECS_MAP.put(DataType.Name.COUNTER, TypeCodec.counter());
        BUILT_IN_CODECS_MAP.put(DataType.Name.DECIMAL, TypeCodec.decimal());
        BUILT_IN_CODECS_MAP.put(DataType.Name.DOUBLE, TypeCodec.cdouble());
        BUILT_IN_CODECS_MAP.put(DataType.Name.FLOAT, TypeCodec.cfloat());
        BUILT_IN_CODECS_MAP.put(DataType.Name.INET, TypeCodec.inet());
        BUILT_IN_CODECS_MAP.put(DataType.Name.INT, TypeCodec.cint());
        BUILT_IN_CODECS_MAP.put(DataType.Name.TEXT, TypeCodec.varchar());
        BUILT_IN_CODECS_MAP.put(DataType.Name.TIMESTAMP, TypeCodec.timestamp());
        BUILT_IN_CODECS_MAP.put(DataType.Name.UUID, TypeCodec.uuid());
        BUILT_IN_CODECS_MAP.put(DataType.Name.VARCHAR, TypeCodec.varchar());
        BUILT_IN_CODECS_MAP.put(DataType.Name.VARINT, TypeCodec.varint());
        BUILT_IN_CODECS_MAP.put(DataType.Name.TIMEUUID, TypeCodec.timeUUID());
        BUILT_IN_CODECS_MAP.put(DataType.Name.SMALLINT, TypeCodec.smallInt());
        BUILT_IN_CODECS_MAP.put(DataType.Name.TINYINT, TypeCodec.tinyInt());
        BUILT_IN_CODECS_MAP.put(DataType.Name.DATE, TypeCodec.date());
        BUILT_IN_CODECS_MAP.put(DataType.Name.TIME, TypeCodec.time());
        BUILT_IN_CODECS_MAP.put(DataType.Name.DURATION, TypeCodec.duration());
    }

    // roughly sorted by popularity
    private static final TypeCodec<?>[] BUILT_IN_CODECS =
    new TypeCodec<?>[]{
    TypeCodec
    .varchar(), // must be declared before AsciiCodec so it gets chosen when CQL type not
    // available
    TypeCodec
    .uuid(), // must be declared before TimeUUIDCodec so it gets chosen when CQL type not
    // available
    TypeCodec.timeUUID(),
    TypeCodec.timestamp(),
    TypeCodec.cint(),
    TypeCodec.bigint(),
    TypeCodec.blob(),
    TypeCodec.cdouble(),
    TypeCodec.cfloat(),
    TypeCodec.decimal(),
    TypeCodec.varint(),
    TypeCodec.inet(),
    TypeCodec.cboolean(),
    TypeCodec.smallInt(),
    TypeCodec.tinyInt(),
    TypeCodec.date(),
    TypeCodec.time(),
    TypeCodec.duration(),
    TypeCodec.counter(),
    TypeCodec.ascii()
    };

    /**
     * Cache key for the codecs cache.
     */
    private static final class CacheKey
    {

        private final DataType cqlType;

        private final TypeToken<?> javaType;

        CacheKey(DataType cqlType, TypeToken<?> javaType)
        {
            this.javaType = javaType;
            this.cqlType = cqlType;
        }

        @Override
        public boolean equals(Object o)
        {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            CacheKey cacheKey = (CacheKey) o;
            return Objects.equals(cqlType, cacheKey.cqlType)
                   && Objects.equals(javaType, cacheKey.javaType);
        }

        @Override
        public int hashCode()
        {
            return Objects.hash(cqlType, javaType);
        }
    }

    /**
     * Cache loader for the codecs cache.
     */
    private class TypeCodecCacheLoader extends CacheLoader<CacheKey, TypeCodec<?>>
    {
        @Override
        public TypeCodec<?> load(CacheKey cacheKey)
        {
            checkNotNull(cacheKey.cqlType, "Parameter cqlType cannot be null");
            if (logger.isTraceEnabled())
                logger.trace(
                "Loading codec into cache: [{} <-> {}]",
                CodecRegistry.toString(cacheKey.cqlType),
                CodecRegistry.toString(cacheKey.javaType));
            for (TypeCodec<?> codec : codecs)
            {
                if (codec.accepts(cacheKey.cqlType)
                    && (cacheKey.javaType == null || codec.accepts(cacheKey.javaType)))
                {
                    logger.trace("Already existing codec found: {}", codec);
                    return codec;
                }
            }
            return createCodec(cacheKey.cqlType, cacheKey.javaType);
        }
    }

    /**
     * A complexity-based weigher for the codecs cache. Weights are computed mainly according to the
     * CQL type:
     *
     * <ol>
     * <li>Manually-registered codecs always weigh 0;
     * <li>Codecs for primitive types weigh 0;
     * <li>Codecs for collections weigh the total weight of their inner types + the weight of their
     * level of deepness;
     * <li>Codecs for UDTs and tuples weigh the total weight of their inner types + the weight of
     * their level of deepness, but cannot weigh less than 1;
     * <li>Codecs for custom (non-CQL) types weigh 1.
     * </ol>
     * <p>
     * A consequence of this algorithm is that codecs for primitive types and codecs for all "shallow"
     * collections thereof are never evicted.
     */
    private class TypeCodecWeigher implements Weigher<CacheKey, TypeCodec<?>>
    {

        @Override
        public int weigh(CacheKey key, TypeCodec<?> value)
        {
            return codecs.contains(value) ? 0 : weigh(value.cqlType, 0);
        }

        private int weigh(DataType cqlType, int level)
        {
            switch (cqlType.getName())
            {
                case LIST:
                case SET:
                case MAP:
                {
                    int weight = level;
                    for (DataType eltType : cqlType.getTypeArguments())
                    {
                        weight += weigh(eltType, level + 1);
                    }
                    return weight;
                }
                case UDT:
                {
                    int weight = level;
                    for (UserType.Field field : ((UserType) cqlType))
                    {
                        weight += weigh(field.getType(), level + 1);
                    }
                    return weight == 0 ? 1 : weight;
                }
                case TUPLE:
                {
                    int weight = level;
                    for (DataType componentType : ((TupleType) cqlType).getComponentTypes())
                    {
                        weight += weigh(componentType, level + 1);
                    }
                    return weight == 0 ? 1 : weight;
                }
                case CUSTOM:
                    return 1;
                default:
                    return 0;
            }
        }
    }

    /**
     * Simple removal listener for the codec cache (can be used for debugging purposes by setting the
     * {@code CodecRegistry} logger level to {@code TRACE}.
     */
    private static class TypeCodecRemovalListener implements RemovalListener<CacheKey, TypeCodec<?>>
    {
        @Override
        public void onRemoval(RemovalNotification<CacheKey, TypeCodec<?>> notification)
        {
            logger.trace(
            "Evicting codec from cache: {} (cause: {})",
            notification.getValue(),
            notification.getCause());
        }
    }

    /**
     * The list of user-registered codecs.
     */
    private final CopyOnWriteArrayList<TypeCodec<?>> codecs;

    /**
     * A LoadingCache to serve requests for codecs whenever possible. The cache can be used as long as
     * at least the CQL type is known.
     */
    private final LoadingCache<CacheKey, TypeCodec<?>> cache;

    /**
     * Creates a new instance initialized with built-in codecs for all the base CQL types.
     */
    public CodecRegistry()
    {
        this.codecs = new CopyOnWriteArrayList<>();
        this.cache = defaultCacheBuilder().build(new TypeCodecCacheLoader());
    }

    private CacheBuilder<CacheKey, TypeCodec<?>> defaultCacheBuilder()
    {
        CacheBuilder<CacheKey, TypeCodec<?>> builder =
        CacheBuilder.newBuilder()
                    // lists, sets and maps of 20 primitive types = 20 + 20 + 20*20 = 440 codecs,
                    // so let's start with roughly 1/4 of that
                    .initialCapacity(100)
                    .maximumWeight(1000)
                    .weigher(new TypeCodecWeigher());
        if (logger.isTraceEnabled())
            // do not bother adding a listener if it will be ineffective
            builder = builder.removalListener(new TypeCodecRemovalListener());
        return builder;
    }

    /**
     * Register the given codec with this registry.
     *
     * <p>This method will log a warning and ignore the codec if it collides with a previously
     * registered one. Note that this check is not done in a completely thread-safe manner; codecs
     * should typically be registered at application startup, not in a highly concurrent context (if a
     * race condition occurs, the worst possible outcome is that no warning gets logged, and the codec
     * gets registered but will never actually be used).
     *
     * @param newCodec The codec to add to the registry.
     * @return this CodecRegistry (for method chaining).
     */
    public CodecRegistry register(TypeCodec<?> newCodec)
    {
        for (TypeCodec<?> oldCodec : BUILT_IN_CODECS)
        {
            if (oldCodec.accepts(newCodec.getCqlType()) && oldCodec.accepts(newCodec.getJavaType()))
            {
                logger.warn(
                "Ignoring codec {} because it collides with previously registered codec {}",
                newCodec,
                oldCodec);
                return this;
            }
        }
        for (TypeCodec<?> oldCodec : codecs)
        {
            if (oldCodec.accepts(newCodec.getCqlType()) && oldCodec.accepts(newCodec.getJavaType()))
            {
                logger.warn(
                "Ignoring codec {} because it collides with previously registered codec {}",
                newCodec,
                oldCodec);
                return this;
            }
        }
        CacheKey key = new CacheKey(newCodec.getCqlType(), newCodec.getJavaType());
        TypeCodec<?> existing = cache.getIfPresent(key);
        if (existing != null)
        {
            logger.warn(
            "Ignoring codec {} because it collides with previously generated codec {}",
            newCodec,
            existing);
            return this;
        }
        this.codecs.add(newCodec);
        return this;
    }

    /**
     * Register the given codecs with this registry.
     *
     * @param codecs The codecs to add to the registry.
     * @return this CodecRegistry (for method chaining).
     * @see #register(TypeCodec)
     */
    public CodecRegistry register(TypeCodec<?>... codecs)
    {
        for (TypeCodec<?> codec : codecs) register(codec);
        return this;
    }

    /**
     * Register the given codecs with this registry.
     *
     * @param codecs The codecs to add to the registry.
     * @return this CodecRegistry (for method chaining).
     * @see #register(TypeCodec)
     */
    public CodecRegistry register(Iterable<? extends TypeCodec<?>> codecs)
    {
        for (TypeCodec<?> codec : codecs) register(codec);
        return this;
    }

    /**
     * Returns a {@link TypeCodec codec} that accepts the given value.
     *
     * <p>This method takes an arbitrary Java object and tries to locate a suitable codec for it.
     * Codecs must perform a {@link TypeCodec#accepts(Object) runtime inspection} of the object to
     * determine if they can accept it or not, which, depending on the implementations, can be
     * expensive; besides, the resulting codec cannot be cached. Therefore there might be a
     * performance penalty when using this method.
     *
     * <p>Furthermore, this method returns the first matching codec, regardless of its accepted CQL
     * type. It should be reserved for situations where the target CQL type is not available or
     * unknown. In the Java driver, this happens mainly when serializing a value in a {@code
     * SimpleStatement#SimpleStatement(String, Object...) SimpleStatement} or in the {@code
     * querybuilder.QueryBuilder}, where no CQL type information is
     * available.
     *
     * <p>Codecs returned by this method are <em>NOT</em> cached (see the {@link CodecRegistry
     * top-level documentation} of this class for more explanations about caching).
     *
     * @param value The value the codec should accept; must not be {@code null}.
     * @return A suitable codec.
     * @throws CodecNotFoundException if a suitable codec cannot be found.
     */
    public <T> TypeCodec<T> codecFor(T value)
    {
        return findCodec(null, value);
    }

    /**
     * Returns a {@link TypeCodec codec} that accepts the given {@link DataType CQL type}.
     *
     * <p>This method returns the first matching codec, regardless of its accepted Java type. It
     * should be reserved for situations where the Java type is not available or unknown. In the Java
     * driver, this happens mainly when deserializing a value using the {@link
     * GettableByIndexData#getObject(int) getObject} method.
     *
     * <p>Codecs returned by this method are cached (see the {@link CodecRegistry top-level
     * documentation} of this class for more explanations about caching).
     *
     * @param cqlType The {@link DataType CQL type} the codec should accept; must not be {@code null}.
     * @return A suitable codec.
     * @throws CodecNotFoundException if a suitable codec cannot be found.
     */
    public <T> TypeCodec<T> codecFor(DataType cqlType) throws CodecNotFoundException
    {
        return lookupCodec(cqlType, null);
    }

    /**
     * Returns a {@link TypeCodec codec} that accepts the given {@link DataType CQL type} and the
     * given Java class.
     *
     * <p>This method can only handle raw (non-parameterized) Java types. For parameterized types, use
     * {@link #codecFor(DataType, TypeToken)} instead.
     *
     * <p>Codecs returned by this method are cached (see the {@link CodecRegistry top-level
     * documentation} of this class for more explanations about caching).
     *
     * @param cqlType  The {@link DataType CQL type} the codec should accept; must not be {@code null}.
     * @param javaType The Java type the codec should accept; can be {@code null}.
     * @return A suitable codec.
     * @throws CodecNotFoundException if a suitable codec cannot be found.
     */
    public <T> TypeCodec<T> codecFor(DataType cqlType, Class<T> javaType)
    throws CodecNotFoundException
    {
        return codecFor(cqlType, TypeToken.of(javaType));
    }

    /**
     * Returns a {@link TypeCodec codec} that accepts the given {@link DataType CQL type} and the
     * given Java type.
     *
     * <p>This method handles parameterized types thanks to Guava's {@link TypeToken} API.
     *
     * <p>Codecs returned by this method are cached (see the {@link CodecRegistry top-level
     * documentation} of this class for more explanations about caching).
     *
     * @param cqlType  The {@link DataType CQL type} the codec should accept; must not be {@code null}.
     * @param javaType The {@link TypeToken Java type} the codec should accept; can be {@code null}.
     * @return A suitable codec.
     * @throws CodecNotFoundException if a suitable codec cannot be found.
     */
    public <T> TypeCodec<T> codecFor(DataType cqlType, TypeToken<T> javaType)
    throws CodecNotFoundException
    {
        return lookupCodec(cqlType, javaType);
    }

    /**
     * Returns a {@link TypeCodec codec} that accepts the given {@link DataType CQL type} and the
     * given value.
     *
     * <p>This method takes an arbitrary Java object and tries to locate a suitable codec for it.
     * Codecs must perform a {@link TypeCodec#accepts(Object) runtime inspection} of the object to
     * determine if they can accept it or not, which, depending on the implementations, can be
     * expensive; besides, the resulting codec cannot be cached. Therefore there might be a
     * performance penalty when using this method.
     *
     * <p>Codecs returned by this method are <em>NOT</em> cached (see the {@link CodecRegistry
     * top-level documentation} of this class for more explanations about caching).
     *
     * @param cqlType The {@link DataType CQL type} the codec should accept; can be {@code null}.
     * @param value   The value the codec should accept; must not be {@code null}.
     * @return A suitable codec.
     * @throws CodecNotFoundException if a suitable codec cannot be found.
     */
    public <T> TypeCodec<T> codecFor(DataType cqlType, T value)
    {
        return findCodec(cqlType, value);
    }

    @SuppressWarnings("unchecked")
    private <T> TypeCodec<T> lookupCodec(DataType cqlType, TypeToken<T> javaType)
    {
        checkNotNull(cqlType, "Parameter cqlType cannot be null");
        TypeCodec<?> codec = BUILT_IN_CODECS_MAP.get(cqlType.getName());
        if (codec != null && (javaType == null || codec.accepts(javaType)))
        {
            logger.trace("Returning built-in codec {}", codec);
            return (TypeCodec<T>) codec;
        }
        if (logger.isTraceEnabled())
            logger.trace("Querying cache for codec [{} <-> {}]", toString(cqlType), toString(javaType));
        try
        {
            CacheKey cacheKey = new CacheKey(cqlType, javaType);
            codec = cache.get(cacheKey);
        }
        catch (UncheckedExecutionException e)
        {
            if (e.getCause() instanceof CodecNotFoundException)
            {
                throw (CodecNotFoundException) e.getCause();
            }
            throw new CodecNotFoundException(e.getCause());
        }
        catch (RuntimeException | ExecutionException e)
        {
            throw new CodecNotFoundException(e.getCause());
        }
        logger.trace("Returning cached codec {}", codec);
        return (TypeCodec<T>) codec;
    }

    @SuppressWarnings("unchecked")
    private <T> TypeCodec<T> findCodec(DataType cqlType, TypeToken<T> javaType)
    {
        checkNotNull(cqlType, "Parameter cqlType cannot be null");
        if (logger.isTraceEnabled())
            logger.trace("Looking for codec [{} <-> {}]", toString(cqlType), toString(javaType));

        // Look at the built-in codecs first
        for (TypeCodec<?> codec : BUILT_IN_CODECS)
        {
            if (codec.accepts(cqlType) && (javaType == null || codec.accepts(javaType)))
            {
                logger.trace("Built-in codec found: {}", codec);
                return (TypeCodec<T>) codec;
            }
        }

        // Look at the user-registered codecs next
        for (TypeCodec<?> codec : codecs)
        {
            if (codec.accepts(cqlType) && (javaType == null || codec.accepts(javaType)))
            {
                logger.trace("Already registered codec found: {}", codec);
                return (TypeCodec<T>) codec;
            }
        }
        return createCodec(cqlType, javaType);
    }

    @SuppressWarnings("unchecked")
    private <T> TypeCodec<T> findCodec(DataType cqlType, T value)
    {
        checkNotNull(value, "Parameter value cannot be null");
        if (logger.isTraceEnabled())
            logger.trace("Looking for codec [{} <-> {}]", toString(cqlType), value.getClass());

        // Look at the built-in codecs first
        for (TypeCodec<?> codec : BUILT_IN_CODECS)
        {
            if ((cqlType == null || codec.accepts(cqlType)) && codec.accepts(value))
            {
                logger.trace("Built-in codec found: {}", codec);
                return (TypeCodec<T>) codec;
            }
        }

        // Look at the user-registered codecs next
        for (TypeCodec<?> codec : codecs)
        {
            if ((cqlType == null || codec.accepts(cqlType)) && codec.accepts(value))
            {
                logger.trace("Already registered codec found: {}", codec);
                return (TypeCodec<T>) codec;
            }
        }
        return createCodec(cqlType, value);
    }

    private <T> TypeCodec<T> createCodec(DataType cqlType, TypeToken<T> javaType)
    {
        TypeCodec<T> codec = maybeCreateCodec(cqlType, javaType);
        if (codec == null) throw notFound(cqlType, javaType);
        // double-check that the created codec satisfies the initial request
        // this check can fail specially when creating codecs for collections
        // e.g. if B extends A and there is a codec registered for A and
        // we request a codec for List<B>, the registry would generate a codec for List<A>
        if (!codec.accepts(cqlType) || (javaType != null && !codec.accepts(javaType)))
            throw notFound(cqlType, javaType);
        logger.trace("Codec created: {}", codec);
        return codec;
    }

    private <T> TypeCodec<T> createCodec(DataType cqlType, T value)
    {
        TypeCodec<T> codec = maybeCreateCodec(cqlType, value);
        if (codec == null) throw notFound(cqlType, TypeToken.of(value.getClass()));
        // double-check that the created codec satisfies the initial request
        if ((cqlType != null && !codec.accepts(cqlType)) || !codec.accepts(value))
            throw notFound(cqlType, TypeToken.of(value.getClass()));
        logger.trace("Codec created: {}", codec);
        return codec;
    }

    @SuppressWarnings("unchecked")
    private <T> TypeCodec<T> maybeCreateCodec(DataType cqlType, TypeToken<T> javaType)
    {
        checkNotNull(cqlType);

        if (cqlType.getName() == LIST
            && (javaType == null || List.class.isAssignableFrom(javaType.getRawType())))
        {
            TypeToken<?> elementType = null;
            if (javaType != null && javaType.getType() instanceof ParameterizedType)
            {
                Type[] typeArguments = ((ParameterizedType) javaType.getType()).getActualTypeArguments();
                elementType = TypeToken.of(typeArguments[0]);
            }
            TypeCodec<?> eltCodec = findCodec(cqlType.getTypeArguments().get(0), elementType);
            return (TypeCodec<T>) TypeCodec.list(eltCodec);
        }

        if (cqlType.getName() == SET
            && (javaType == null || Set.class.isAssignableFrom(javaType.getRawType())))
        {
            TypeToken<?> elementType = null;
            if (javaType != null && javaType.getType() instanceof ParameterizedType)
            {
                Type[] typeArguments = ((ParameterizedType) javaType.getType()).getActualTypeArguments();
                elementType = TypeToken.of(typeArguments[0]);
            }
            TypeCodec<?> eltCodec = findCodec(cqlType.getTypeArguments().get(0), elementType);
            return (TypeCodec<T>) TypeCodec.set(eltCodec);
        }

        if (cqlType.getName() == MAP
            && (javaType == null || Map.class.isAssignableFrom(javaType.getRawType())))
        {
            TypeToken<?> keyType = null;
            TypeToken<?> valueType = null;
            if (javaType != null && javaType.getType() instanceof ParameterizedType)
            {
                Type[] typeArguments = ((ParameterizedType) javaType.getType()).getActualTypeArguments();
                keyType = TypeToken.of(typeArguments[0]);
                valueType = TypeToken.of(typeArguments[1]);
            }
            TypeCodec<?> keyCodec = findCodec(cqlType.getTypeArguments().get(0), keyType);
            TypeCodec<?> valueCodec = findCodec(cqlType.getTypeArguments().get(1), valueType);
            return (TypeCodec<T>) TypeCodec.map(keyCodec, valueCodec);
        }

        if (cqlType instanceof TupleType
            && (javaType == null || TupleValue.class.isAssignableFrom(javaType.getRawType())))
        {
            return (TypeCodec<T>) TypeCodec.tuple((TupleType) cqlType);
        }

        if (cqlType instanceof UserType
            && (javaType == null || UDTValue.class.isAssignableFrom(javaType.getRawType())))
        {
            return (TypeCodec<T>) TypeCodec.userType((UserType) cqlType);
        }

        if (cqlType instanceof DataType.CustomType
            && (javaType == null || ByteBuffer.class.isAssignableFrom(javaType.getRawType())))
        {
            return (TypeCodec<T>) TypeCodec.custom((DataType.CustomType) cqlType);
        }

        return null;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private <T> TypeCodec<T> maybeCreateCodec(DataType cqlType, T value)
    {
        checkNotNull(value);

        if ((cqlType == null || cqlType.getName() == LIST) && value instanceof List)
        {
            List list = (List) value;
            if (list.isEmpty())
            {
                DataType elementType =
                (cqlType == null || cqlType.getTypeArguments().isEmpty())
                ? DataType.blob()
                : cqlType.getTypeArguments().get(0);
                return (TypeCodec<T>) TypeCodec.list(findCodec(elementType, (TypeToken) null));
            }
            else
            {
                DataType elementType =
                (cqlType == null || cqlType.getTypeArguments().isEmpty())
                ? null
                : cqlType.getTypeArguments().get(0);
                return (TypeCodec<T>) TypeCodec.list(findCodec(elementType, list.iterator().next()));
            }
        }

        if ((cqlType == null || cqlType.getName() == SET) && value instanceof Set)
        {
            Set set = (Set) value;
            if (set.isEmpty())
            {
                DataType elementType =
                (cqlType == null || cqlType.getTypeArguments().isEmpty())
                ? DataType.blob()
                : cqlType.getTypeArguments().get(0);
                return (TypeCodec<T>) TypeCodec.set(findCodec(elementType, (TypeToken) null));
            }
            else
            {
                DataType elementType =
                (cqlType == null || cqlType.getTypeArguments().isEmpty())
                ? null
                : cqlType.getTypeArguments().get(0);
                return (TypeCodec<T>) TypeCodec.set(findCodec(elementType, set.iterator().next()));
            }
        }

        if ((cqlType == null || cqlType.getName() == MAP) && value instanceof Map)
        {
            Map map = (Map) value;
            if (map.isEmpty())
            {
                DataType keyType =
                (cqlType == null || cqlType.getTypeArguments().size() < 1)
                ? DataType.blob()
                : cqlType.getTypeArguments().get(0);
                DataType valueType =
                (cqlType == null || cqlType.getTypeArguments().size() < 2)
                ? DataType.blob()
                : cqlType.getTypeArguments().get(1);
                return (TypeCodec<T>) TypeCodec.map(
                findCodec(keyType, (TypeToken) null), findCodec(valueType, (TypeToken) null));
            }
            else
            {
                DataType keyType =
                (cqlType == null || cqlType.getTypeArguments().size() < 1)
                ? null
                : cqlType.getTypeArguments().get(0);
                DataType valueType =
                (cqlType == null || cqlType.getTypeArguments().size() < 2)
                ? null
                : cqlType.getTypeArguments().get(1);
                Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
                return (TypeCodec<T>)
                       TypeCodec.map(
                       findCodec(keyType, entry.getKey()), findCodec(valueType, entry.getValue()));
            }
        }

        if ((cqlType == null || cqlType.getName() == DataType.Name.TUPLE)
            && value instanceof TupleValue)
        {
            return (TypeCodec<T>)
                   TypeCodec.tuple(cqlType == null ? ((TupleValue) value).getType() : (TupleType) cqlType);
        }

        if ((cqlType == null || cqlType.getName() == DataType.Name.UDT) && value instanceof UDTValue)
        {
            return (TypeCodec<T>)
                   TypeCodec.userType(cqlType == null ? ((UDTValue) value).getType() : (UserType) cqlType);
        }

        if ((cqlType instanceof DataType.CustomType)
            && value instanceof ByteBuffer)
        {
            return (TypeCodec<T>) TypeCodec.custom((DataType.CustomType) cqlType);
        }

        return null;
    }

    private static CodecNotFoundException notFound(DataType cqlType, TypeToken<?> javaType)
    {
        String msg =
        String.format(
        "Codec not found for requested operation: [%s <-> %s]",
        toString(cqlType), toString(javaType));
        return new CodecNotFoundException(msg);
    }

    private static String toString(Object value)
    {
        return value == null ? "ANY" : value.toString();
    }
}
