/**
 * 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>
#include <chrono>
#include "xyz/openbmc_project/Example/Iface1/server.hpp"
#include "xyz/openbmc_project/Example/Iface2/server.hpp"

using namespace std::literals::chrono_literals;
using namespace std::literals::string_literals;

using Object = phosphor::inventory::manager::Object;
using ObjectMap = std::map<sdbusplus::message::object_path, Object>;

constexpr auto MGR_SERVICE = "phosphor.inventory.test.mgr";
constexpr auto MGR_INTERFACE = IFACE;
constexpr auto MGR_ROOT = "/testing/inventory";
constexpr auto EXAMPLE_SERVICE = "phosphor.inventory.test.example";
constexpr auto EXAMPLE_ROOT = "/testing";

const auto trigger1 = sdbusplus::message::object_path(EXAMPLE_ROOT +
                      "/trigger1"s);
const auto trigger2 = sdbusplus::message::object_path(EXAMPLE_ROOT +
                      "/trigger2"s);
const auto trigger3 = sdbusplus::message::object_path(EXAMPLE_ROOT +
                      "/trigger3"s);
const auto trigger4 = sdbusplus::message::object_path(EXAMPLE_ROOT +
                      "/trigger4"s);
const auto trigger5 = sdbusplus::message::object_path(EXAMPLE_ROOT +
                      "/trigger5"s);

const sdbusplus::message::object_path relDeleteMeOne{"/deleteme1"};
const sdbusplus::message::object_path relDeleteMeTwo{"/deleteme2"};
const sdbusplus::message::object_path relDeleteMeThree{"/deleteme3"};

const std::string root{MGR_ROOT};
const std::string deleteMeOne{root + relDeleteMeOne.str};
const std::string deleteMeTwo{root + relDeleteMeTwo.str};
const std::string deleteMeThree{root + relDeleteMeThree.str};

using ExampleIface1 = sdbusplus::xyz::openbmc_project::Example::server::Iface1;
using ExampleIface2 = sdbusplus::xyz::openbmc_project::Example::server::Iface2;

/** @class ExampleService
 *  @brief Host an object for triggering events.
 */
struct ExampleService
{
    ~ExampleService() = default;
    ExampleService() :
        shutdown(false),
        bus(sdbusplus::bus::new_default()),
        objmgr(sdbusplus::server::manager::manager(bus, MGR_ROOT))
    {
        bus.request_name(EXAMPLE_SERVICE);
    }

    void run()
    {
        sdbusplus::server::object::object <
        ExampleIface1, ExampleIface2 > t1(bus, trigger1.str.c_str());
        sdbusplus::server::object::object <
        ExampleIface1, ExampleIface2 > t2(bus, trigger2.str.c_str());
        sdbusplus::server::object::object <
        ExampleIface1, ExampleIface2 > t3(bus, trigger3.str.c_str());
        sdbusplus::server::object::object <
        ExampleIface1, ExampleIface2 > t4(bus, trigger4.str.c_str());
        sdbusplus::server::object::object <
        ExampleIface1, ExampleIface2 > t5(bus, trigger5.str.c_str());

        while (!shutdown)
        {
            bus.process_discard();
            bus.wait((5000000us).count());
        }
    }

    volatile bool shutdown;
    sdbusplus::bus::bus bus;
    sdbusplus::server::manager::manager objmgr;
};


/** @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;
};

/**@brief Find a subset of interfaces and properties in an object. */
auto hasProperties(const Object& l, const Object& r)
{
    Object 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. */
auto hasInterfaces(const std::vector<std::string>& l, const Object& 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()
{
    const std::string exampleRoot{EXAMPLE_ROOT};
    auto b = sdbusplus::bus::new_default();

    auto notify = [&]()
    {
        return b.new_method_call(
                   MGR_SERVICE,
                   MGR_ROOT,
                   MGR_INTERFACE,
                   "Notify");
    };
    auto set = [&](const std::string & path)
    {
        return b.new_method_call(
                   EXAMPLE_SERVICE,
                   path.c_str(),
                   "org.freedesktop.DBus.Properties",
                   "Set");
    };

    Object obj
    {
        {
            "xyz.openbmc_project.Example.Iface1",
            {{"ExampleProperty1", "test1"s}}
        },
        {
            "xyz.openbmc_project.Example.Iface2",
            {{"ExampleProperty2", "test2"s}, {"ExampleProperty3", 0ll}}
        },
    };

    // Validate startup events occurred.
    {
        sdbusplus::message::object_path relCreateMe3{"/createme3"};
        std::string createMe3{root + relCreateMe3.str};

        auto get = b.new_method_call(
                       MGR_SERVICE,
                       createMe3.c_str(),
                       "org.freedesktop.DBus.Properties",
                       "GetAll");
        get.append("xyz.openbmc_project.Example.Iface1");
        auto resp = b.call(get);

        Object::mapped_type properties;
        assert(!resp.is_method_error());
        resp.read(properties);
    }

    // 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(ObjectMap({{relPath, obj}}));
        b.call(m);

        auto sig{queue.pop()};
        assert(sig);
        sdbusplus::message::object_path signalPath;
        Object signalObjectType;
        sig.read(signalPath);
        assert(path == signalPath.str);
        sig.read(signalObjectType);
        assert(hasProperties(signalObjectType, obj));
        auto moreSignals{queue.pop()};
        assert(!moreSignals);
    }

    // Validate the propertyIs filter.
    {
        // Create an object to be deleted.
        {
            auto m = notify();
            m.append(ObjectMap({{relDeleteMeThree, obj}}));
            b.call(m);
        }

        // Validate that the action does not run if the property doesn't match.
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger4.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("123"));
            b.call(m);
            auto sig{queue.pop()};
            assert(!sig);
        }

        // Validate that the action does run if the property matches.
        {
            // Set ExampleProperty2 to something else to the 123 filter
            // matches.
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger4.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("xyz"));
            b.call(m);
            auto sig{queue.pop()};
            assert(!sig);
        }
        {
            // Set ExampleProperty3 to 99.
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger4.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty3");
            m.append(sdbusplus::message::variant<int64_t>(99));
            b.call(m);
            auto sig{queue.pop()};
            assert(!sig);
        }
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger4.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty2");
            m.append(sdbusplus::message::variant<std::string>("123"));
            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 == deleteMeThree);
                sig.read(interfaces);
                std::sort(interfaces.begin(), interfaces.end());
                assert(hasInterfaces(interfaces, obj));
            }
        }
    }

    // Make sure DBus signals are handled.
    {
        // Create some objects to be deleted by an action.
        {
            auto m = notify();
            m.append(ObjectMap({{relDeleteMeOne, obj}}));
            b.call(m);
        }
        {
            auto m = notify();
            m.append(ObjectMap({{relDeleteMeTwo, obj}}));
            b.call(m);
        }
        {
            auto m = notify();
            m.append(ObjectMap({{relDeleteMeThree, obj}}));
            b.call(m);
        }

        // Set some properties that should not trigger due to a filter.
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger1.str);
            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);
        }
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");
            auto m = set(trigger3.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty3");
            m.append(sdbusplus::message::variant<int64_t>(11));
            b.call(m);
            auto sig{queue.pop()};
            assert(!sig);
        }

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

            auto m = set(trigger1.str);
            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);
            }
        }
        {
            SignalQueue queue(
                "path='" + root + "',member='InterfacesRemoved'");

            auto m = set(trigger3.str);
            m.append("xyz.openbmc_project.Example.Iface2");
            m.append("ExampleProperty3");
            m.append(sdbusplus::message::variant<int64_t>(10));
            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 == deleteMeThree);
                sig.read(interfaces);
                std::sort(interfaces.begin(), interfaces.end());
                assert(hasInterfaces(interfaces, obj));
            }
            {
                // Make sure there was only one signal.
                auto sig{queue.pop()};
                assert(!sig);
            }
        }
    }

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

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

        // Trigger and validate the change.
        {
            SignalQueue queue(
                "path='" + changeMe + "',member='PropertiesChanged'");
            auto m = set(trigger2.str);
            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");
            }
        }
    }

    // Validate the create object action.
    {
        sdbusplus::message::object_path relCreateMe1{"/createme1"};
        sdbusplus::message::object_path relCreateMe2{"/createme2"};
        std::string createMe1{root + relCreateMe1.str};
        std::string createMe2{root + relCreateMe2.str};

        // Trigger the action.
        {
            sdbusplus::message::object_path signalPath;
            Object signalObject;

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

            auto m = set(trigger5.str);
            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);
                sig.read(signalPath);
                assert(createMe1 == signalPath.str);
                sig.read(signalObject);
            }
            {
                auto sig{queue.pop()};
                assert(sig);
                sig.read(signalPath);
                assert(createMe2 == signalPath.str);
                sig.read(signalObject);
            }

            auto moreSignals{queue.pop()};
            assert(!moreSignals);
        }
    }
}

int main()
{
    phosphor::inventory::manager::Manager mgr(
        sdbusplus::bus::new_default(),
        MGR_SERVICE, MGR_ROOT, MGR_INTERFACE);
    ExampleService d;

    auto f1 = [](auto mgr)
    {
        mgr->run();
    };
    auto f2 = [](auto d)
    {
        d->run();
    };

    auto t1 = std::thread(f1, &mgr);
    auto t2 = std::thread(f2, &d);

    runTests();

    mgr.shutdown();
    d.shutdown = true;

    // Wait for server threads to exit.
    t1.join();
    t2.join();
    std::cout << "Success!  Waiting for threads to exit..." << std::endl;

    return 0;
}

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