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

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.transport.messages.ErrorMessage;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static org.apache.cassandra.transport.Message.Direction.*;

public class ProtocolErrorTest {

    @BeforeClass
    public static void setupDD()
    {
        DatabaseDescriptor.daemonInitialization();
    }

    @Test
    public void testInvalidProtocolVersion() throws Exception
    {
        // test using a protocol 2 version higher than the current version (1 version higher is current beta)
        testInvalidProtocolVersion(ProtocolVersion.CURRENT.asInt() + 2); //
        // test using a protocol version lower than the lowest version
        for (ProtocolVersion version : ProtocolVersion.UNSUPPORTED)
            testInvalidProtocolVersion(version.asInt());

    }

    public void testInvalidProtocolVersion(int version) throws Exception
    {
        Frame.Decoder dec = new Frame.Decoder(null, ProtocolVersionLimit.SERVER_DEFAULT);

        List<Object> results = new ArrayList<>();
        byte[] frame = new byte[] {
                (byte) REQUEST.addToVersion(version),  // direction & version
                0x00,  // flags
                0x00, 0x01,  // stream ID
                0x09,  // opcode
                0x00, 0x00, 0x00, 0x21,  // body length
                0x00, 0x00, 0x00, 0x1b, 0x00, 0x1b, 0x53, 0x45,
                0x4c, 0x45, 0x43, 0x54, 0x20, 0x2a, 0x20, 0x46,
                0x52, 0x4f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74,
                0x65, 0x6d, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
                0x3b
        };
        ByteBuf buf = Unpooled.wrappedBuffer(frame);
        try {
            dec.decode(null, buf, results);
            Assert.fail("Expected protocol error");
        } catch (ProtocolException e) {
            Assert.assertTrue(e.getMessage().contains("Invalid or unsupported protocol version"));
        }
    }

    @Test
    public void testInvalidProtocolVersionShortFrame() throws Exception
    {
        // test for CASSANDRA-11464
        Frame.Decoder dec = new Frame.Decoder(null, ProtocolVersionLimit.SERVER_DEFAULT);

        List<Object> results = new ArrayList<>();
        byte[] frame = new byte[] {
                (byte) REQUEST.addToVersion(1),  // direction & version
                0x00,  // flags
                0x01,  // stream ID
                0x09,  // opcode
                0x00, 0x00, 0x00, 0x21,  // body length
        };
        ByteBuf buf = Unpooled.wrappedBuffer(frame);
        try {
            dec.decode(null, buf, results);
            Assert.fail("Expected protocol error");
        } catch (ProtocolException e) {
            Assert.assertTrue(e.getMessage().contains("Invalid or unsupported protocol version"));
        }
    }

    @Test
    public void testInvalidDirection() throws Exception
    {
        Frame.Decoder dec = new Frame.Decoder(null, ProtocolVersionLimit.SERVER_DEFAULT);

        List<Object> results = new ArrayList<>();
        // should generate a protocol exception for using a response frame with
        // a prepare op, ensure that it comes back with stream ID 1
        byte[] frame = new byte[] {
                (byte) RESPONSE.addToVersion(ProtocolVersion.CURRENT.asInt()),  // direction & version
                0x00,  // flags
                0x00, 0x01,  // stream ID
                0x09,  // opcode
                0x00, 0x00, 0x00, 0x21,  // body length
                0x00, 0x00, 0x00, 0x1b, 0x00, 0x1b, 0x53, 0x45,
                0x4c, 0x45, 0x43, 0x54, 0x20, 0x2a, 0x20, 0x46,
                0x52, 0x4f, 0x4d, 0x20, 0x73, 0x79, 0x73, 0x74,
                0x65, 0x6d, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
                0x3b
        };
        ByteBuf buf = Unpooled.wrappedBuffer(frame);
        try {
            dec.decode(null, buf, results);
            Assert.fail("Expected protocol error");
        } catch (ErrorMessage.WrappedException e) {
            // make sure the exception has the correct stream ID
            Assert.assertEquals(1, e.getStreamId());
            Assert.assertTrue(e.getMessage().contains("Wrong protocol direction"));
        }
    }

    @Test
    public void testBodyLengthOverLimit() throws Exception
    {
        Frame.Decoder dec = new Frame.Decoder(null, ProtocolVersionLimit.SERVER_DEFAULT);

        List<Object> results = new ArrayList<>();
        byte[] frame = new byte[] {
                (byte) REQUEST.addToVersion(ProtocolVersion.CURRENT.asInt()),  // direction & version
                0x00,  // flags
                0x00, 0x01,  // stream ID
                0x09,  // opcode
                0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00,  // body length
        };
        byte[] body = new byte[0x10000000];
        ByteBuf buf = Unpooled.wrappedBuffer(frame, body);
        try {
            dec.decode(null, buf, results);
            Assert.fail("Expected protocol error");
        } catch (ErrorMessage.WrappedException e) {
            // make sure the exception has the correct stream ID
            Assert.assertEquals(1, e.getStreamId());
            Assert.assertTrue(e.getMessage().contains("Request is too big"));
        }
    }

    @Test
    public void testErrorMessageWithNullString() throws Exception
    {
        // test for CASSANDRA-11167
        ErrorMessage msg = ErrorMessage.fromException(new ServerError((String) null));
        assert msg.toString().endsWith("null") : msg.toString();
        int size = ErrorMessage.codec.encodedSize(msg, ProtocolVersion.CURRENT);
        ByteBuf buf = Unpooled.buffer(size);
        ErrorMessage.codec.encode(msg, buf, ProtocolVersion.CURRENT);

        ByteBuf expected = Unpooled.wrappedBuffer(new byte[]{
                0x00, 0x00, 0x00, 0x00,  // int error code
                0x00, 0x00               // short message length
        });

        Assert.assertEquals(expected, buf);
    }
}
