/*
 *
 * 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.
 *
 */
#include "qpid/client/Connection.h"
#include "qpid/client/Connector.h"
#include "qpid/framing/AMQP_HighestVersion.h"
#include "qpid/framing/ProtocolVersion.h"
#include "qpid/framing/all_method_bodies.h"
#include "qpid/framing/amqp_framing.h"
#include "qpid/framing/reply_exceptions.h"
#include "qpid/framing/FieldValue.h"
#include "unit_test.h"

#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <iostream>

#include <memory>
#include <sstream>
#include <typeinfo>

using namespace qpid;
using namespace qpid::framing;
using namespace std;

namespace qpid {
namespace tests {

template <class T>
std::string tostring(const T& x)
{
    std::ostringstream out;
    out << x;
    return out.str();
}

QPID_AUTO_TEST_SUITE(FramingTestSuite)

QPID_AUTO_TEST_CASE(testMessageTransferBody)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    MessageTransferBody in(version, "my-exchange", 1, 1);
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    MessageTransferBody out(version);
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(testConnectionSecureBody)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    std::string s = "security credential";
    ConnectionSecureBody in(version, s);
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    ConnectionSecureBody out(version);
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(testConnectionRedirectBody)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    std::string a = "hostA";
    std::string b = "hostB";
    Array hosts(0x95);
    hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(a)));
    hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(b)));

    ConnectionRedirectBody in(version, a, hosts);
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    ConnectionRedirectBody out(version);
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(testQueueDeclareBody)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    QueueDeclareBody in(version, "name", "dlq", true, false, true, false, FieldTable());
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    QueueDeclareBody out(version);
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(testConnectionRedirectBodyFrame)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    std::string a = "hostA";
    std::string b = "hostB";
    Array hosts(0x95);
    hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(a)));
    hosts.add(boost::shared_ptr<FieldValue>(new Str16Value(b)));

    AMQFrame in((ConnectionRedirectBody(version, a, hosts)));
    in.setChannel(999);
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    AMQFrame out;
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(testMessageCancelBodyFrame)
{
    char buffer[1024];
    ProtocolVersion version(highestProtocolVersion);
    Buffer wbuff(buffer, sizeof(buffer));
    AMQFrame in((MessageCancelBody(version, "tag")));
    in.setChannel(999);
    in.encode(wbuff);

    Buffer rbuff(buffer, sizeof(buffer));
    AMQFrame out;
    out.decode(rbuff);
    BOOST_CHECK_EQUAL(tostring(in), tostring(out));
}

QPID_AUTO_TEST_CASE(badStrings) {
    char data[(65535 + 2) + (255 + 1)];
    Buffer b(data, sizeof(data));
    BOOST_CHECK_THROW(b.putShortString(std::string(256, 'X')),
                      Exception);
    BOOST_CHECK_THROW(b.putMediumString(std::string(65536, 'X')),
                      Exception);
    b.putShortString(std::string(255, 'X'));
    b.putMediumString(std::string(65535, 'X'));
}

QPID_AUTO_TEST_SUITE_END()

}} // namespace qpid::tests
