/*
 * 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.qpid.tests.protocol.v1_0.transport.connection;

import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.both;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;

import java.net.InetSocketAddress;

import org.junit.Test;

import org.apache.qpid.server.protocol.v1_0.type.UnsignedInteger;
import org.apache.qpid.server.protocol.v1_0.type.UnsignedShort;
import org.apache.qpid.server.protocol.v1_0.type.transport.AmqpError;
import org.apache.qpid.server.protocol.v1_0.type.transport.Close;
import org.apache.qpid.server.protocol.v1_0.type.transport.ConnectionError;
import org.apache.qpid.server.protocol.v1_0.type.transport.Error;
import org.apache.qpid.server.protocol.v1_0.type.transport.Open;
import org.apache.qpid.tests.utils.BrokerAdmin;
import org.apache.qpid.tests.protocol.v1_0.FrameTransport;
import org.apache.qpid.tests.protocol.v1_0.Interaction;
import org.apache.qpid.tests.protocol.v1_0.EmptyResponse;
import org.apache.qpid.tests.utils.BrokerAdminUsingTestBase;
import org.apache.qpid.tests.protocol.SpecificationTest;
import org.apache.qpid.tests.utils.BrokerSpecific;


public class OpenTest extends BrokerAdminUsingTestBase
{
    @Test
    @SpecificationTest(section = "1.3.4",
            description = "Open without mandatory fields should result in a decoding error.")
    public void emptyOpen() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            final Interaction interaction = transport.newInteraction();
            Open responseOpen = interaction.negotiateProtocol().consumeResponse()
                                           .openContainerId(null)
                                           .open().consumeResponse()
                                           .getLatestResponse(Open.class);
            assertThat(responseOpen.getContainerId(), is(notNullValue()));

            Close responseClose = interaction.consumeResponse().getLatestResponse(Close.class);

            // 2.7.9: If set, this field indicates that the connection is being closed due to an error condition.
            // The value of the field SHOULD contain details on the cause of the error.
            Error error = responseClose.getError();
            if (error != null)
            {
                assertThat(error.getCondition(), anyOf(equalTo(AmqpError.DECODE_ERROR), equalTo(AmqpError.INVALID_FIELD)));
            }
        }
    }

    @Test
    @SpecificationTest(section = "2.4.1",
            description = "Each AMQP connection begins with an exchange of capabilities and limitations, "
                          + "including the maximum frame size.")
    public void successfulOpen() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            Interaction interaction = transport.newInteraction();
            final Open responseOpen = interaction.negotiateProtocol().consumeResponse()
                                                 .openContainerId("testContainerId")
                                                 .open().consumeResponse()
                                                 .getLatestResponse(Open.class);

            assertThat(responseOpen.getContainerId(), is(notNullValue()));
            assertThat(responseOpen.getMaxFrameSize(),
                       is(anyOf(nullValue(),
                                both(greaterThan(UnsignedInteger.ZERO)).and(lessThanOrEqualTo(UnsignedInteger.MAX_VALUE)))));
            assertThat(responseOpen.getChannelMax(),
                       is(anyOf(nullValue(),
                                both(greaterThanOrEqualTo(UnsignedShort.ZERO)).and(lessThanOrEqualTo(UnsignedShort.MAX_VALUE)))));

            interaction.doCloseConnection();
        }
    }

    @Test
    @SpecificationTest(section = "2.4.5",
            description = "Implementations MUST be prepared to handle empty frames arriving on any valid channel")
    public void emptyFrame() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            Interaction interaction = transport.newInteraction();
            interaction.negotiateProtocol().consumeResponse()
                       .openContainerId("testContainerId")
                       .open().consumeResponse(Open.class)
                       .emptyFrame()
                       .doCloseConnection();
        }
    }

    @Test
    @SpecificationTest(section = "2.4.5",
            description = "Connections are subject to an idle timeout threshold.")
    public void idleTimeout() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            Interaction interaction = transport.newInteraction();
            final int idleTimeOut = 1000;
            Open responseOpen = interaction.negotiateProtocol().consumeResponse()
                                           .openContainerId("testContainerId")
                                           .openIdleTimeOut(idleTimeOut)
                                           .open().consumeResponse()
                                           .getLatestResponse(Open.class);

            final UnsignedInteger peerIdleTimeOut = responseOpen.getIdleTimeOut();
            assertThat(peerIdleTimeOut, is(anyOf(nullValue(), greaterThanOrEqualTo(UnsignedInteger.ZERO))));

            final int timeout = peerIdleTimeOut == null || peerIdleTimeOut.intValue() == 0
                    ? idleTimeOut
                    : peerIdleTimeOut.intValue();
            Thread.sleep(timeout);
            interaction.consumeResponse(EmptyResponse.class);
        }
    }

    @Test
    @SpecificationTest(section = "2.4.1",
            description = "The open frame can only be sent on channel 0. §2.7.1: A peer that receives a channel number"
                          + " outside the supported range MUST close the connection with the framing-error error-code.")
    public void failOpenOnChannelNotZero() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            final Interaction interaction = transport.newInteraction();
            Open responseOpen = interaction.negotiateProtocol().consumeResponse()
                                           .openContainerId("testContainerId")
                                           .connectionChannel(UnsignedShort.valueOf((short) 1))
                                           .open().consumeResponse()
                                           .getLatestResponse(Open.class);
            assertThat(responseOpen.getContainerId(), is(notNullValue()));

            Close responseClose = interaction.consumeResponse(Close.class).getLatestResponse(Close.class);

            // 2.7.9: If set, this field indicates that the connection is being closed due to an error condition.
            // The value of the field SHOULD contain details on the cause of the error.
            Error error = responseClose.getError();
            if (error != null)
            {
                assertThat(error.getCondition(), equalTo(ConnectionError.FRAMING_ERROR));
            }
        }
    }

    @Test
    @SpecificationTest(section = "2.7.1", description = "The name of the host (either fully qualified or relative) to which the sending peer is connecting")
    @BrokerSpecific(kind = BrokerAdmin.KIND_BROKER_J)
    public void failOpenOnNonExistingHostname() throws Exception
    {
        final InetSocketAddress addr = getBrokerAdmin().getBrokerAddress(BrokerAdmin.PortType.ANONYMOUS_AMQP);
        try (FrameTransport transport = new FrameTransport(addr).connect())
        {
            final Interaction interaction = transport.newInteraction();
            Open responseOpen = interaction.negotiateProtocol().consumeResponse()
                                           .openContainerId("testContainerId")
                                           .openHostname("non-existing-virtual-host-" + System.currentTimeMillis())
                                           .open().consumeResponse()
                                           .getLatestResponse(Open.class);
            assertThat(responseOpen.getContainerId(), is(notNullValue()));

            Close responseClose = interaction.consumeResponse().getLatestResponse(Close.class);
            assertThat(responseClose.getError(), is(notNullValue()));
            assertThat(responseClose.getError().getCondition(), equalTo(AmqpError.NOT_FOUND));
        }
    }
}
