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

import java.nio.ByteBuffer;
import java.util.UUID;

import com.google.common.collect.Iterables;
import org.apache.cassandra.service.paxos.PrepareVerbHandler;
import org.apache.cassandra.service.paxos.ProposeVerbHandler;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.Util;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.rows.Row;
import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.gms.Gossiper;
import org.apache.cassandra.service.paxos.Commit;
import org.apache.cassandra.service.paxos.PaxosState;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.UUIDGen;

import static org.junit.Assert.*;

public class PaxosStateTest
{
    @BeforeClass
    public static void setUpClass() throws Throwable
    {
        SchemaLoader.loadSchema();
        SchemaLoader.schemaDefinition("PaxosStateTest");
    }

    @AfterClass
    public static void stopGossiper()
    {
        Gossiper.instance.stop();
    }

    @Test
    public void testCommittingAfterTruncation() throws Exception
    {
        ColumnFamilyStore cfs = Keyspace.open("PaxosStateTestKeyspace1").getColumnFamilyStore("Standard1");
        String key = "key" + System.nanoTime();
        ByteBuffer value = ByteBufferUtil.bytes(0);
        RowUpdateBuilder builder = new RowUpdateBuilder(cfs.metadata(), FBUtilities.timestampMicros(), key);
        builder.clustering("a").add("val", value);
        PartitionUpdate update = Iterables.getOnlyElement(builder.build().getPartitionUpdates());

        // CFS should be empty initially
        assertNoDataPresent(cfs, Util.dk(key));

        // Commit the proposal & verify the data is present
        Commit beforeTruncate = newProposal(0, update);
        PaxosState.commit(beforeTruncate);
        assertDataPresent(cfs, Util.dk(key), "val", value);

        // Truncate then attempt to commit again, mutation should
        // be ignored as the proposal predates the truncation
        cfs.truncateBlocking();
        PaxosState.commit(beforeTruncate);
        assertNoDataPresent(cfs, Util.dk(key));

        // Now try again with a ballot created after the truncation
        long timestamp = SystemKeyspace.getTruncatedAt(update.metadata().id) + 1;
        Commit afterTruncate = newProposal(timestamp, update);
        PaxosState.commit(afterTruncate);
        assertDataPresent(cfs, Util.dk(key), "val", value);
    }

    private Commit newProposal(long ballotMillis, PartitionUpdate update)
    {
        return Commit.newProposal(UUIDGen.getTimeUUID(ballotMillis), update);
    }

    private void assertDataPresent(ColumnFamilyStore cfs, DecoratedKey key, String name, ByteBuffer value)
    {
        Row row = Util.getOnlyRowUnfiltered(Util.cmd(cfs, key).build());
        assertEquals(0, ByteBufferUtil.compareUnsigned(value,
                row.getCell(cfs.metadata().getColumn(ByteBufferUtil.bytes(name))).buffer()));
    }

    private void assertNoDataPresent(ColumnFamilyStore cfs, DecoratedKey key)
    {
        Util.assertEmpty(Util.cmd(cfs, key).build());
    }

    @Test
    public void testPrepareProposePaxos() throws Throwable
    {
        ColumnFamilyStore cfs = Keyspace.open("PaxosStateTestKeyspace1").getColumnFamilyStore("Standard1");
        String key = "key" + System.nanoTime();
        ByteBuffer value = ByteBufferUtil.bytes(0);
        RowUpdateBuilder builder = new RowUpdateBuilder(cfs.metadata(), FBUtilities.timestampMicros(), key);
        builder.clustering("a").add("val", value);
        PartitionUpdate update = Iterables.getOnlyElement(builder.build().getPartitionUpdates());

        // CFS should be empty initially
        assertNoDataPresent(cfs, Util.dk(key));

        UUID ballot = UUIDGen.getRandomTimeUUIDFromMicros(System.currentTimeMillis());

        Commit commit = Commit.newPrepare(Util.dk(key), cfs.metadata(), ballot);

        assertTrue("paxos prepare stage failed", PrepareVerbHandler.doPrepare(commit).promised);
        assertTrue("paxos propose stage failed", ProposeVerbHandler.doPropose(commit));
    }
}
