/*
 * 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.db;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.*;

import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.io.util.*;
import org.apache.cassandra.utils.memory.AbstractAllocator;

/**
 * The clustering column values for a row.
 * <p>
 * A {@code Clustering} is a {@code ClusteringPrefix} that must always be "complete", i.e. have
 * as many values as there is clustering columns in the table it is part of. It is the clustering
 * prefix used by rows.
 * <p>
 * Note however that while it's size must be equal to the table clustering size, a clustering can have
 * {@code null} values, and this mostly for thrift backward compatibility (in practice, if a value is null,
 * all of the following ones will be too because that's what thrift allows, but it's never assumed by the
 * code so we could start generally allowing nulls for clustering columns if we wanted to).
 */
public class Clustering extends AbstractClusteringPrefix
{
    public static final Serializer serializer = new Serializer();

    /**
     * The special cased clustering used by all static rows. It is a special case in the
     * sense that it's always empty, no matter how many clustering columns the table has.
     */
    public static final Clustering STATIC_CLUSTERING = new Clustering(EMPTY_VALUES_ARRAY)
    {
        @Override
        public Kind kind()
        {
            return Kind.STATIC_CLUSTERING;
        }

        @Override
        public String toString()
        {
            return "STATIC";
        }

        @Override
        public String toString(CFMetaData metadata)
        {
            return toString();
        }
    };

    /** Empty clustering for tables having no clustering columns. */
    public static final Clustering EMPTY = new Clustering(EMPTY_VALUES_ARRAY)
    {
        @Override
        public String toString(CFMetaData metadata)
        {
            return "EMPTY";
        }
    };

    public Clustering(ByteBuffer... values)
    {
        super(Kind.CLUSTERING, values);
    }

    public Kind kind()
    {
        return Kind.CLUSTERING;
    }

    public Clustering copy(AbstractAllocator allocator)
    {
        // Important for STATIC_CLUSTERING (but no point in being wasteful in general).
        if (size() == 0)
            return this;

        ByteBuffer[] newValues = new ByteBuffer[size()];
        for (int i = 0; i < size(); i++)
            newValues[i] = values[i] == null ? null : allocator.clone(values[i]);
        return new Clustering(newValues);
    }

    public String toString(CFMetaData metadata)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size(); i++)
        {
            ColumnDefinition c = metadata.clusteringColumns().get(i);
            sb.append(i == 0 ? "" : ", ").append(c.name).append('=').append(get(i) == null ? "null" : c.type.getString(get(i)));
        }
        return sb.toString();
    }

    public String toCQLString(CFMetaData metadata)
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size(); i++)
        {
            ColumnDefinition c = metadata.clusteringColumns().get(i);
            sb.append(i == 0 ? "" : ", ").append(c.type.getString(get(i)));
        }
        return sb.toString();
    }

    /**
     * Serializer for Clustering object.
     * <p>
     * Because every clustering in a given table must have the same size (ant that size cannot actually change once the table
     * has been defined), we don't record that size.
     */
    public static class Serializer
    {
        public void serialize(Clustering clustering, DataOutputPlus out, int version, List<AbstractType<?>> types) throws IOException
        {
            assert clustering != STATIC_CLUSTERING : "We should never serialize a static clustering";
            assert clustering.size() == types.size() : "Invalid clustering for the table: " + clustering;
            ClusteringPrefix.serializer.serializeValuesWithoutSize(clustering, out, version, types);
        }

        public ByteBuffer serialize(Clustering clustering, int version, List<AbstractType<?>> types)
        {
            try (DataOutputBuffer buffer = new DataOutputBuffer((int)serializedSize(clustering, version, types)))
            {
                serialize(clustering, buffer, version, types);
                return buffer.buffer();
            }
            catch (IOException e)
            {
                throw new RuntimeException("Writting to an in-memory buffer shouldn't trigger an IOException", e);
            }
        }

        public long serializedSize(Clustering clustering, int version, List<AbstractType<?>> types)
        {
            return ClusteringPrefix.serializer.valuesWithoutSizeSerializedSize(clustering, version, types);
        }

        public Clustering deserialize(DataInputPlus in, int version, List<AbstractType<?>> types) throws IOException
        {
            if (types.isEmpty())
                return EMPTY;

            ByteBuffer[] values = ClusteringPrefix.serializer.deserializeValuesWithoutSize(in, types.size(), version, types);
            return new Clustering(values);
        }

        public Clustering deserialize(ByteBuffer in, int version, List<AbstractType<?>> types)
        {
            try (DataInputBuffer buffer = new DataInputBuffer(in, true))
            {
                return deserialize(buffer, version, types);
            }
            catch (IOException e)
            {
                throw new RuntimeException("Reading from an in-memory buffer shouldn't trigger an IOException", e);
            }
        }
    }
}
