/**
 * Copyright © 2016 IBM Corporation
 *
 * Licensed 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 "../manager.hpp"
#include "../config.h"
#include <cassert>
#include <iostream>
#include <algorithm>
#include <thread>

constexpr auto SERVICE = "phosphor.inventory.test";
constexpr auto INTERFACE = IFACE;
constexpr auto ROOT = "/testing/inventory";

/** @class SignalQueue
 *  @brief Store DBus signals in a queue.
 */
class SignalQueue
{
    public:
        ~SignalQueue() = default;
        SignalQueue() = delete;
        SignalQueue(const SignalQueue&) = delete;
        SignalQueue(SignalQueue&&) = default;
        SignalQueue& operator=(const SignalQueue&) = delete;
        SignalQueue& operator=(SignalQueue&&) = default;
        explicit SignalQueue(const std::string& match) :
            _bus(sdbusplus::bus::new_default()),
            _match(_bus, match.c_str(), &callback, this),
            _next(nullptr)
        {
        }

        auto&& pop(unsigned timeout = 1000000)
        {
            while (timeout > 0 && !_next)
            {
                _bus.process_discard();
                _bus.wait(50000);
                timeout -= 50000;
            }
            return std::move(_next);
        }

    private:
        static int callback(sd_bus_message* m, void* context, sd_bus_error*)
        {
            auto* me = static_cast<SignalQueue*>(context);
            sd_bus_message_ref(m);
            sdbusplus::message::message msg{m};
            me->_next = std::move(msg);
            return 0;
        }

        sdbusplus::bus::bus _bus;
        sdbusplus::server::match::match _match;
        sdbusplus::message::message _next;
};

template <typename ...T>
using Object = std::map <
               std::string,
               std::map <
               std::string,
               sdbusplus::message::variant<T... >>>;

/**@brief Find a subset of interfaces and properties in an object. */
template <typename ...T>
auto hasProperties(const Object<T...>& l, const Object<T...>& r)
{
    Object<T...> result;
    std::set_difference(
        r.cbegin(),
        r.cend(),
        l.cbegin(),
        l.cend(),
        std::inserter(result, result.end()));
    return result.empty();
}

/**@brief Check an object for one or more interfaces. */
template <typename ...T>
auto hasInterfaces(const std::vector<std::string>& l, const Object<T...>& r)
{
    std::vector<std::string> stripped, interfaces;
    std::transform(
        r.cbegin(),
        r.cend(),
        std::back_inserter(stripped),
        [](auto & p)
    {
        return p.first;
    });
    std::set_difference(
        stripped.cbegin(),
        stripped.cend(),
        l.cbegin(),
        l.cend(),
        std::back_inserter(interfaces));
    return interfaces.empty();
}

void runTests(phosphor::inventory::manager::Manager& mgr)
{
    const std::string root{ROOT};
    auto b = sdbusplus::bus::new_default();
    auto notify = [&]()
    {
        return b.new_method_call(
                   SERVICE,
                   ROOT,
                   INTERFACE,
                   "Notify");
    };
    auto set = [&](const std::string & path)
    {
        return b.new_method_call(
                   SERVICE,
                   path.c_str(),
                   "org.freedesktop.DBus.Properties",
                   "Set");
    };

    Object<std::string> obj
    {
        {
            "xyz.openbmc_project.Example.Iface1",
            {{"ExampleProperty1", "test1"}}
        },
        {
            "xyz.openbmc_project.Example.Iface2",
            {{"ExampleProperty2", "test2"}}
        },
    };

    // Make sure the notify method works.
    {
        sdbusplus::message::object_path relPath{"/foo"};
        std::string path(root + relPath.str);

        SignalQueue queue(
            "path='" + root + "',member='InterfacesAdded'");

        auto m = notify();
        m.append(relPath);
        m.append(obj);
        b.call(m);

        auto sig{queue.pop()};
        assert(sig);
        sdbusplus::message::object_path signalPath;
        Object<std::string> signalObject;
        sig.read(signalPath);
        assert(path == signalPath);
        sig.read(signalObject);
        assert(hasProperties(signalObject, obj));
        auto moreSignals{queue.pop()};
        assert(!moreSignals);
    }

    // Make sure DBus signals are handled.
    {
        sdbusplus::message::object_path relDeleteMeOne{"/deleteme1"};
        sdbusplus::message::object_path relDeleteMeTwo{"/deleteme2"};
        sdbusplus::message::object_path relTriggerOne{"/trigger1"};
        std::string deleteMeOne{root + relDeleteMeOne.str};
        std::string deleteMeTwo{root + relDeleteMeTwo.str};
        std::string triggerOne{root + relTriggerOne.str};

        // Create some objects to be deleted by an action.
        {
            auto m = notify();
            m.append(relDeleteMeOne);
            m.append(obj);
            b.call(m);
        }
        {
            auto m = notify();
            m.append(relDeleteMeTwo);
            m.append(obj);
            b.call(m);
        }

        // Create the triggering object.
        {
            auto m = notify();
            m.append(relTriggerOne);
            m.append(obj);
            b.call(m);
        }

        // Set a property that should not trigger due to a filter.
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(triggerOne);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("abc123"));
            b.call(m);
            auto sig{queue.pop()};
            assert(!sig);
        }

        // Set a property that should trigger.
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");

            auto m = set(triggerOne);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("xxxyyy"));
            b.call(m);

            sdbusplus::message::object_path sigpath;
            std::vector<std::string> interfaces;
            {
                std::vector<std::string> interfaces;
                auto sig{queue.pop()};
                assert(sig);
                sig.read(sigpath);
                assert(sigpath == deleteMeOne);
                sig.read(interfaces);
                std::sort(interfaces.begin(), interfaces.end());
                assert(hasInterfaces(interfaces, obj));
            }
            {
                std::vector<std::string> interfaces;
                auto sig{queue.pop()};
                assert(sig);
                sig.read(sigpath);
                assert(sigpath == deleteMeTwo);
                sig.read(interfaces);
                std::sort(interfaces.begin(), interfaces.end());
                assert(hasInterfaces(interfaces, obj));
            }
            {
                // Make sure there were only two signals.
                auto sig{queue.pop()};
                assert(!sig);
            }
        }
    }

    // Validate the set property action.
    {
        sdbusplus::message::object_path relChangeMe{"/changeme"};
        sdbusplus::message::object_path relTriggerTwo{"/trigger2"};
        std::string changeMe{root + relChangeMe.str};
        std::string triggerTwo{root + relTriggerTwo.str};

        // Create an object to be updated by the set property action.
        {
            auto m = notify();
            m.append(relChangeMe);
            m.append(obj);
            b.call(m);
        }

        // Create the triggering object.
        {
            auto m = notify();
            m.append(relTriggerTwo);
            m.append(obj);
            b.call(m);
        }

        // Trigger and validate the change.
        {
            SignalQueue queue(
                "path='" + changeMe + "',member='PropertiesChanged'");
            auto m = set(triggerTwo);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("yyyxxx"));
            b.call(m);

            std::string sigInterface;
            std::map <
            std::string,
                sdbusplus::message::variant<std::string >> sigProperties;
            {
                std::vector<std::string> interfaces;
                auto sig{queue.pop()};
                sig.read(sigInterface);
                assert(sigInterface == "xyz.openbmc_project.Example.Iface1");
                sig.read(sigProperties);
                assert(sigProperties["ExampleProperty1"] == "changed");
            }
        }
    }

    mgr.shutdown();
    std::cout << "Success!" << std::endl;
}

int main()
{
    phosphor::inventory::manager::Manager mgr(
        sdbusplus::bus::new_default(),
        SERVICE, ROOT, INTERFACE);

    auto f = [](auto mgr)
    {
        mgr->run();
    };
    auto t = std::thread(f, &mgr);
    runTests(mgr);

    // Wait for server thread to exit.
    t.join();

    return 0;
}

// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
