/*
* 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 static org.junit.Assert.*;

import java.io.*;

import com.google.common.base.Predicate;

import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.Util;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.db.commitlog.CommitLogTestReplayer;
import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.db.rows.Row;
import org.apache.cassandra.db.marshal.AsciiType;
import org.apache.cassandra.db.marshal.BytesType;
import org.apache.cassandra.db.partitions.FilteredPartition;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.io.IVersionedSerializer;
import org.apache.cassandra.io.util.DataInputBuffer;
import org.apache.cassandra.io.util.DataInputPlus;
import org.apache.cassandra.io.util.DataOutputBuffer;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.schema.KeyspaceParams;
import org.apache.cassandra.utils.ByteBufferUtil;

public class ReadMessageTest
{
    private static final String KEYSPACE1 = "ReadMessageTest1";
    private static final String KEYSPACENOCOMMIT = "ReadMessageTest_NoCommit";
    private static final String CF = "Standard1";
    private static final String CF_FOR_READ_TEST = "Standard2";
    private static final String CF_FOR_COMMIT_TEST = "Standard3";

    @BeforeClass
    public static void defineSchema() throws ConfigurationException
    {
        CFMetaData cfForReadMetadata = CFMetaData.Builder.create(KEYSPACE1, CF_FOR_READ_TEST)
                                                            .addPartitionKey("key", BytesType.instance)
                                                            .addClusteringColumn("col1", AsciiType.instance)
                                                            .addClusteringColumn("col2", AsciiType.instance)
                                                            .addRegularColumn("a", AsciiType.instance)
                                                            .addRegularColumn("b", AsciiType.instance).build();

        CFMetaData cfForCommitMetadata1 = CFMetaData.Builder.create(KEYSPACE1, CF_FOR_COMMIT_TEST)
                                                       .addPartitionKey("key", BytesType.instance)
                                                       .addClusteringColumn("name", AsciiType.instance)
                                                       .addRegularColumn("commit1", AsciiType.instance).build();

        CFMetaData cfForCommitMetadata2 = CFMetaData.Builder.create(KEYSPACENOCOMMIT, CF_FOR_COMMIT_TEST)
                                                            .addPartitionKey("key", BytesType.instance)
                                                            .addClusteringColumn("name", AsciiType.instance)
                                                            .addRegularColumn("commit2", AsciiType.instance).build();

        SchemaLoader.prepareServer();
        SchemaLoader.createKeyspace(KEYSPACE1,
                                    KeyspaceParams.simple(1),
                                    SchemaLoader.standardCFMD(KEYSPACE1, CF),
                                    cfForReadMetadata,
                                    cfForCommitMetadata1);
        SchemaLoader.createKeyspace(KEYSPACENOCOMMIT,
                                    KeyspaceParams.simpleTransient(1),
                                    SchemaLoader.standardCFMD(KEYSPACENOCOMMIT, CF),
                                    cfForCommitMetadata2);
    }

    @Test
    public void testMakeReadMessage() throws IOException
    {
        ColumnFamilyStore cfs = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF_FOR_READ_TEST);
        ReadCommand rm, rm2;

        rm = Util.cmd(cfs, Util.dk("key1"))
                 .includeRow("col1", "col2")
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs, Util.dk("key1"))
                 .includeRow("col1", "col2")
                 .reverse()
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs)
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs)
                 .fromKeyIncl(ByteBufferUtil.bytes("key1"))
                 .toKeyIncl(ByteBufferUtil.bytes("key2"))
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs)
                 .columns("a")
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs)
                 .includeRow("col1", "col2")
                 .columns("a")
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());

        rm = Util.cmd(cfs)
                 .fromKeyIncl(ByteBufferUtil.bytes("key1"))
                 .includeRow("col1", "col2")
                 .columns("a")
                 .build();
        rm2 = serializeAndDeserializeReadMessage(rm);
        assertEquals(rm.toString(), rm2.toString());
    }

    private ReadCommand serializeAndDeserializeReadMessage(ReadCommand rm) throws IOException
    {
        IVersionedSerializer<ReadCommand> rms = ReadCommand.serializer;
        DataOutputBuffer out = new DataOutputBuffer();

        rms.serialize(rm, out, MessagingService.current_version);

        DataInputPlus dis = new DataInputBuffer(out.getData());
        return rms.deserialize(dis, MessagingService.current_version);
    }


    @Test
    public void testGetColumn()
    {
        ColumnFamilyStore cfs = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF);

        new RowUpdateBuilder(cfs.metadata, 0, ByteBufferUtil.bytes("key1"))
                .clustering("Column1")
                .add("val", ByteBufferUtil.bytes("abcd"))
                .build()
                .apply();

        ColumnDefinition col = cfs.metadata.getColumnDefinition(ByteBufferUtil.bytes("val"));
        int found = 0;
        for (FilteredPartition partition : Util.getAll(Util.cmd(cfs).build()))
        {
            for (Row r : partition)
            {
                if (r.getCell(col).value().equals(ByteBufferUtil.bytes("abcd")))
                    ++found;
            }
        }
        assertEquals(1, found);
    }

    @Test
    public void testNoCommitLog() throws Exception
    {
        ColumnFamilyStore cfs = Keyspace.open(KEYSPACE1).getColumnFamilyStore(CF_FOR_COMMIT_TEST);

        ColumnFamilyStore cfsnocommit = Keyspace.open(KEYSPACENOCOMMIT).getColumnFamilyStore(CF_FOR_COMMIT_TEST);

        new RowUpdateBuilder(cfs.metadata, 0, ByteBufferUtil.bytes("row"))
                .clustering("c")
                .add("commit1", ByteBufferUtil.bytes("abcd"))
                .build()
                .apply();

        new RowUpdateBuilder(cfsnocommit.metadata, 0, ByteBufferUtil.bytes("row"))
                .clustering("c")
                .add("commit2", ByteBufferUtil.bytes("abcd"))
                .build()
                .apply();

        Checker checker = new Checker(cfs.metadata.getColumnDefinition(ByteBufferUtil.bytes("commit1")),
                                      cfsnocommit.metadata.getColumnDefinition(ByteBufferUtil.bytes("commit2")));
        CommitLogTestReplayer.examineCommitLog(checker);

        assertTrue(checker.commitLogMessageFound);
        assertFalse(checker.noCommitLogMessageFound);
    }

    static class Checker implements Predicate<Mutation>
    {
        private final ColumnDefinition withCommit;
        private final ColumnDefinition withoutCommit;

        boolean commitLogMessageFound = false;
        boolean noCommitLogMessageFound = false;

        public Checker(ColumnDefinition withCommit, ColumnDefinition withoutCommit)
        {
            this.withCommit = withCommit;
            this.withoutCommit = withoutCommit;
        }

        public boolean apply(Mutation mutation)
        {
            for (PartitionUpdate upd : mutation.getPartitionUpdates())
            {
                Row r = upd.getRow(new Clustering(ByteBufferUtil.bytes("c")));
                if (r != null)
                {
                    if (r.getCell(withCommit) != null)
                        commitLogMessageFound = true;
                    if (r.getCell(withoutCommit) != null)
                        noCommitLogMessageFound = true;
                }
            }
            return true;
        }
    }
}
