/**************************************************************
 *
 * 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 "precompiled_cppuhelper.hxx"

#include "com/sun/star/lang/XEventListener.hpp"
#include "cppuhelper/interfacecontainer.hxx"
#include "cppuhelper/queryinterface.hxx"
#include "cppuhelper/implbase1.hxx"
#include "cppuhelper/propshlp.hxx"
#include "gtest/gtest.h"

using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;

class ContainerListener;

struct ContainerStats {
    int m_nAlive;
    int m_nDisposed;
    ContainerStats() : m_nAlive(0), m_nDisposed(0) {}
};

class ContainerListener : public ::cppu::WeakImplHelper1< XEventListener >
{
    ContainerStats *m_pStats;
public:
    ContainerListener(ContainerStats *pStats)
        : m_pStats(pStats) { m_pStats->m_nAlive++; }
    virtual ~ContainerListener() { m_pStats->m_nAlive--; }
    virtual void SAL_CALL disposing( const EventObject& )
        throw (RuntimeException)
    {
        m_pStats->m_nDisposed++;
    }
};

namespace cppu_ifcontainer
{
    class IfTest : public ::testing::Test
    {
    protected:
        osl::Mutex m_aGuard;
        static const int nTests = 10;
    public:

        template < typename ContainerType, typename ContainedType >
        void doContainerTest(const ContainedType *pTypes)
        {
            ContainerStats aStats;
            ContainerType *pContainer;
            pContainer = new ContainerType(m_aGuard);

            int i;
            Reference<XEventListener> xRefs[nTests * 2];

            // add these interfaces
            for (i = 0; i < nTests * 2; i++)
            {
                xRefs[i] = new ContainerListener(&aStats);
                pContainer->addInterface(pTypes[i / 2], xRefs[i]);
            }

            // check it is all there
            for (i = 0; i < nTests; i++)
            {
                cppu::OInterfaceContainerHelper *pHelper;

                pHelper = pContainer->getContainer(pTypes[i]);

                ASSERT_TRUE(pHelper != NULL) << "no helper";
                Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
                ASSERT_TRUE(aSeq.getLength() == 2) << "wrong num elements";
                ASSERT_TRUE(aSeq[0] == xRefs[i*2]) << "match";
                ASSERT_TRUE(aSeq[1] == xRefs[i*2+1]) << "match";
            }

            // remove every other interface
            for (i = 0; i < nTests; i++)
                pContainer->removeInterface(pTypes[i], xRefs[i*2+1]);

            // check it is half there
            for (i = 0; i < nTests; i++)
            {
                cppu::OInterfaceContainerHelper *pHelper;

                pHelper = pContainer->getContainer(pTypes[i]);

                ASSERT_TRUE(pHelper != NULL) << "no helper";
                Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
                ASSERT_TRUE(aSeq.getLength() == 1) << "wrong num elements";
                ASSERT_TRUE(aSeq[0] == xRefs[i*2]) << "match";
            }

            // remove the 1st half of the rest
            for (i = 0; i < nTests / 2; i++)
                pContainer->removeInterface(pTypes[i], xRefs[i*2]);

            // check it is half there
            for (i = 0; i < nTests / 2; i++)
            {
                cppu::OInterfaceContainerHelper *pHelper;

                pHelper = pContainer->getContainer(pTypes[i]);
                ASSERT_TRUE(pHelper != NULL) << "no helper";
                Sequence<Reference< XInterface > > aSeq = pHelper->getElements();
                ASSERT_TRUE(aSeq.getLength() == 0) << "wrong num elements";
            }

            delete pContainer;
        }
    };

    TEST_F(IfTest, testCreateDispose)
    {
        ContainerStats aStats;
        cppu::OInterfaceContainerHelper *pContainer;

        pContainer = new cppu::OInterfaceContainerHelper(m_aGuard);

        ASSERT_TRUE(pContainer->getLength() == 0) << "Empty container not empty";

        int i;
        for (i = 0; i < nTests; i++)
        {
            Reference<XEventListener> xRef = new ContainerListener(&aStats);
            int nNewLen = pContainer->addInterface(xRef);

            ASSERT_TRUE(nNewLen == i + 1) << "addition length mismatch";
            ASSERT_TRUE(pContainer->getLength() == i + 1) << "addition length mismatch";
        }
        ASSERT_TRUE(aStats.m_nAlive == nTests) << "alive count mismatch";

        EventObject aObj;
        pContainer->disposeAndClear(aObj);

        ASSERT_TRUE(aStats.m_nDisposed == nTests) << "dispose count mismatch";
        ASSERT_TRUE(aStats.m_nAlive == 0) << "leaked container left alive";

        delete pContainer;
    }

    TEST_F(IfTest, testEnumerate)
    {
        int i;
        ContainerStats aStats;
        cppu::OInterfaceContainerHelper *pContainer;
        pContainer = new cppu::OInterfaceContainerHelper(m_aGuard);

        std::vector< Reference< XEventListener > > aListeners;
        for (i = 0; i < nTests; i++)
        {
            Reference<XEventListener> xRef = new ContainerListener(&aStats);
            pContainer->addInterface(xRef);
            aListeners.push_back(xRef);
        }
        Sequence< Reference< XInterface > > aElements;
        aElements = pContainer->getElements();

        ASSERT_TRUE((int)aElements.getLength() == nTests) << "query contents";
        if ((int)aElements.getLength() == nTests)
        {
            for (i = 0; i < nTests; i++)
            {
                ASSERT_TRUE(aElements[i] == aListeners[i]) << "mismatching elements";
            }
        }
        pContainer->clear();

        ASSERT_TRUE(pContainer->getLength() == 0) << "non-empty container post clear";
        delete pContainer;
    }

    TEST_F(IfTest, testOMultiTypeInterfaceContainerHelper)
    {
        uno::Type pTypes[nTests] =
        {
            ::cppu::UnoType< bool >::get(),
            ::cppu::UnoType< float >::get(),
            ::cppu::UnoType< double >::get(),
            ::cppu::UnoType< ::sal_uInt64 >::get(),
            ::cppu::UnoType< ::sal_Int64 >::get(),
            ::cppu::UnoType< ::sal_uInt32 >::get(),
            ::cppu::UnoType< ::sal_Int32 >::get(),
            ::cppu::UnoType< ::sal_Int16 >::get(),
            ::cppu::UnoType< ::rtl::OUString >::get(),
            ::cppu::UnoType< ::sal_Int8 >::get()
        };
        doContainerTest< cppu::OMultiTypeInterfaceContainerHelper,
            uno::Type> (pTypes);
    }

    TEST_F(IfTest, testOMultiTypeInterfaceContainerHelperInt32)
    {
        sal_Int32 pTypes[nTests] =
        {
            0,
            -1,
            1,
            256,
            1024,
            3,
            7,
            8,
            9,
            10
        };
        doContainerTest< cppu::OMultiTypeInterfaceContainerHelperInt32, sal_Int32> (pTypes);
    }

    TEST_F(IfTest, testOMultiTypeInterfaceContainerHelperVar)
    {
        typedef ::cppu::OMultiTypeInterfaceContainerHelperVar<
            const char*, rtl::CStringHash, rtl::CStringEqual> StrContainer;

        const char *pTypes[nTests] =
        {
            "this_is", "such", "fun", "writing", "unit", "tests", "when", "it", "works", "anyway"
        };
        doContainerTest< StrContainer, const char *> (pTypes);
    }


} // namespace cppu_ifcontainer
