/*
 * 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.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.Collections;
import java.util.UUID;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import org.apache.cassandra.AbstractSerializationsTester;
import org.apache.cassandra.Util;
import org.apache.cassandra.Util.PartitionerSwitcher;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.dht.IPartitioner;
import org.apache.cassandra.dht.RandomPartitioner;
import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
import org.apache.cassandra.io.util.DataInputPlus.DataInputStreamPlus;
import org.apache.cassandra.io.util.DataOutputStreamPlus;
import org.apache.cassandra.net.MessageIn;
import org.apache.cassandra.net.MessagingService;
import org.apache.cassandra.repair.NodePair;
import org.apache.cassandra.repair.RepairJobDesc;
import org.apache.cassandra.repair.Validator;
import org.apache.cassandra.repair.messages.*;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.MerkleTrees;

public class SerializationsTest extends AbstractSerializationsTester
{
    private static PartitionerSwitcher partitionerSwitcher;
    private static UUID RANDOM_UUID;
    private static Range<Token> FULL_RANGE;
    private static RepairJobDesc DESC;

    @BeforeClass
    public static void defineSchema() throws Exception
    {
        DatabaseDescriptor.daemonInitialization();
        partitionerSwitcher = Util.switchPartitioner(RandomPartitioner.instance);
        RANDOM_UUID = UUID.fromString("b5c3d033-75aa-4c2f-a819-947aac7a0c54");
        FULL_RANGE = new Range<>(Util.testPartitioner().getMinimumToken(), Util.testPartitioner().getMinimumToken());
        DESC = new RepairJobDesc(getVersion() < MessagingService.VERSION_21 ? null : RANDOM_UUID, RANDOM_UUID, "Keyspace1", "Standard1", Arrays.asList(FULL_RANGE));
    }

    @AfterClass
    public static void tearDown()
    {
        partitionerSwitcher.close();
    }
    
    private void testRepairMessageWrite(String fileName, RepairMessage... messages) throws IOException
    {
        try (DataOutputStreamPlus out = getOutput(fileName))
        {
            for (RepairMessage message : messages)
            {
                testSerializedSize(message, RepairMessage.serializer);
                RepairMessage.serializer.serialize(message, out, getVersion());
            }
            // also serialize MessageOut
            for (RepairMessage message : messages)
                message.createMessage().serialize(out,  getVersion());
        }
    }

    private void testValidationRequestWrite() throws IOException
    {
        ValidationRequest message = new ValidationRequest(DESC, 1234);
        testRepairMessageWrite("service.ValidationRequest.bin", message);
    }

    @Test
    public void testValidationRequestRead() throws IOException
    {
        if (EXECUTE_WRITES)
            testValidationRequestWrite();

        try (DataInputStreamPlus in = getInput("service.ValidationRequest.bin"))
        {
            RepairMessage message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.VALIDATION_REQUEST;
            assert DESC.equals(message.desc);
            assert ((ValidationRequest) message).gcBefore == 1234;

            assert MessageIn.read(in, getVersion(), -1) != null;
        }
    }

    private void testValidationCompleteWrite() throws IOException
    {
        IPartitioner p = RandomPartitioner.instance;

        MerkleTrees mt = new MerkleTrees(p);

        // empty validation
        mt.addMerkleTree((int) Math.pow(2, 15), FULL_RANGE);
        Validator v0 = new Validator(DESC, FBUtilities.getBroadcastAddress(),  -1);
        ValidationComplete c0 = new ValidationComplete(DESC, mt);

        // validation with a tree
        mt = new MerkleTrees(p);
        mt.addMerkleTree(Integer.MAX_VALUE, FULL_RANGE);
        for (int i = 0; i < 10; i++)
            mt.split(p.getRandomToken());
        Validator v1 = new Validator(DESC, FBUtilities.getBroadcastAddress(), -1);
        ValidationComplete c1 = new ValidationComplete(DESC, mt);

        // validation failed
        ValidationComplete c3 = new ValidationComplete(DESC);

        testRepairMessageWrite("service.ValidationComplete.bin", c0, c1, c3);
    }

    @Test
    public void testValidationCompleteRead() throws IOException
    {
        if (EXECUTE_WRITES)
            testValidationCompleteWrite();

        try (DataInputStreamPlus in = getInput("service.ValidationComplete.bin"))
        {
            // empty validation
            RepairMessage message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.VALIDATION_COMPLETE;
            assert DESC.equals(message.desc);

            assert ((ValidationComplete) message).success();
            assert ((ValidationComplete) message).trees != null;

            // validation with a tree
            message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.VALIDATION_COMPLETE;
            assert DESC.equals(message.desc);

            assert ((ValidationComplete) message).success();
            assert ((ValidationComplete) message).trees != null;

            // failed validation
            message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.VALIDATION_COMPLETE;
            assert DESC.equals(message.desc);

            assert !((ValidationComplete) message).success();
            assert ((ValidationComplete) message).trees == null;

            // MessageOuts
            for (int i = 0; i < 3; i++)
                assert MessageIn.read(in, getVersion(), -1) != null;
        }
    }

    private void testSyncRequestWrite() throws IOException
    {
        InetAddress local = InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
        InetAddress src = InetAddress.getByAddress(new byte[]{127, 0, 0, 2});
        InetAddress dest = InetAddress.getByAddress(new byte[]{127, 0, 0, 3});
        SyncRequest message = new SyncRequest(DESC, local, src, dest, Collections.singleton(FULL_RANGE));

        testRepairMessageWrite("service.SyncRequest.bin", message);
    }

    @Test
    public void testSyncRequestRead() throws IOException
    {
        if (EXECUTE_WRITES)
            testSyncRequestWrite();

        InetAddress local = InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
        InetAddress src = InetAddress.getByAddress(new byte[]{127, 0, 0, 2});
        InetAddress dest = InetAddress.getByAddress(new byte[]{127, 0, 0, 3});

        try (DataInputStreamPlus in = getInput("service.SyncRequest.bin"))
        {
            RepairMessage message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.SYNC_REQUEST;
            assert DESC.equals(message.desc);
            assert local.equals(((SyncRequest) message).initiator);
            assert src.equals(((SyncRequest) message).src);
            assert dest.equals(((SyncRequest) message).dst);
            assert ((SyncRequest) message).ranges.size() == 1 && ((SyncRequest) message).ranges.contains(FULL_RANGE);

            assert MessageIn.read(in, getVersion(), -1) != null;
        }
    }

    private void testSyncCompleteWrite() throws IOException
    {
        InetAddress src = InetAddress.getByAddress(new byte[]{127, 0, 0, 2});
        InetAddress dest = InetAddress.getByAddress(new byte[]{127, 0, 0, 3});
        // sync success
        SyncComplete success = new SyncComplete(DESC, src, dest, true);
        // sync fail
        SyncComplete fail = new SyncComplete(DESC, src, dest, false);

        testRepairMessageWrite("service.SyncComplete.bin", success, fail);
    }

    @Test
    public void testSyncCompleteRead() throws IOException
    {
        if (EXECUTE_WRITES)
            testSyncCompleteWrite();

        InetAddress src = InetAddress.getByAddress(new byte[]{127, 0, 0, 2});
        InetAddress dest = InetAddress.getByAddress(new byte[]{127, 0, 0, 3});
        NodePair nodes = new NodePair(src, dest);

        try (DataInputStreamPlus in = getInput("service.SyncComplete.bin"))
        {
            // success
            RepairMessage message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.SYNC_COMPLETE;
            assert DESC.equals(message.desc);

            assert nodes.equals(((SyncComplete) message).nodes);
            assert ((SyncComplete) message).success;

            // fail
            message = RepairMessage.serializer.deserialize(in, getVersion());
            assert message.messageType == RepairMessage.Type.SYNC_COMPLETE;
            assert DESC.equals(message.desc);

            assert nodes.equals(((SyncComplete) message).nodes);
            assert !((SyncComplete) message).success;

            // MessageOuts
            for (int i = 0; i < 2; i++)
                assert MessageIn.read(in, getVersion(), -1) != null;
        }
    }
}
