/*
 * 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/broker/QueueRegistry.h"
#include "qpid/broker/Queue.h"
#include "qpid/broker/QueueSettings.h"
#include "unit_test.h"
#include <string>

using namespace qpid::broker;

namespace qpid {
namespace tests {

QPID_AUTO_TEST_SUITE(QueueRegistryTest)

QPID_AUTO_TEST_CASE(testDeclare)
{
    std::string foo("foo");
    std::string bar("bar");
    QueueRegistry reg;
    std::pair<Queue::shared_ptr,  bool> qc;

    qc = reg.declare(foo, QueueSettings());
    Queue::shared_ptr q = qc.first;
    BOOST_CHECK(q);
    BOOST_CHECK(qc.second); // New queue
    BOOST_CHECK_EQUAL(foo, q->getName());

    qc = reg.declare(foo, QueueSettings());
    BOOST_CHECK_EQUAL(q, qc.first);
    BOOST_CHECK(!qc.second);

    qc = reg.declare(bar, QueueSettings());
    q = qc.first;
    BOOST_CHECK(q);
    BOOST_CHECK_EQUAL(true, qc.second);
    BOOST_CHECK_EQUAL(bar, q->getName());
}

QPID_AUTO_TEST_CASE(testFind)
{
    std::string foo("foo");
    std::string bar("bar");
    QueueRegistry reg;
    std::pair<Queue::shared_ptr,  bool> qc;

    BOOST_CHECK(reg.find(foo) == 0);

    reg.declare(foo, QueueSettings());
    reg.declare(bar, QueueSettings());
    Queue::shared_ptr q = reg.find(bar);
    BOOST_CHECK(q);
    BOOST_CHECK_EQUAL(bar, q->getName());
}

QPID_AUTO_TEST_CASE(testDestroy)
{
    std::string foo("foo");
    QueueRegistry reg;
    std::pair<Queue::shared_ptr,  bool> qc;

    qc = reg.declare(foo, QueueSettings());
    reg.destroy(qc.first);
    // Queue is gone from the registry.
    BOOST_CHECK(reg.find(foo) == 0);
    // Queue is not actually destroyed till we drop our reference.
    BOOST_CHECK_EQUAL(foo, qc.first->getName());
    // We shoud be the only reference.
    BOOST_CHECK_EQUAL(1L, qc.first.use_count());
}

QPID_AUTO_TEST_SUITE_END()

}} // namespace qpid::tests
