/*
 * 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.ByteBufferUtil;
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 ClusteringPrefix minimize()
    {
        if (!ByteBufferUtil.canMinimize(values))
            return this;
        return new Clustering(ByteBufferUtil.minimizeBuffers(values));
    }

    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);
            }
        }
    }
}
