module d_webservice_example.business.todo_notification_service;

class TodoNotificationService
{
    import d_webservice_example.data.todo_notification : TodoNotification;
    import d_webservice_example.enums.todo_notification_type : TodoNotificationType;
    import d_webservice_example.mapper.todo_mapper : asTodoTO;
    import d_webservice_example.model.todo : Todo;
    import std.traits : EnumMembers;

private:
    bool[void delegate(scope TodoNotification) @safe] listeners;

public:
    this() const nothrow pure @nogc @safe
    {
    }

    void registerListener(scope void delegate(scope const TodoNotification) @safe listener) @safe
    {
        listeners[listener] = true;
    }

    void unRegisterListener(scope void delegate(scope const TodoNotification) @safe listener) @safe
    {
        listeners.remove(listener);
    }

    static foreach (method; EnumMembers!TodoNotificationType)
    {
        import std.conv: to;
        import std.format : format;
        mixin(format!q{
            void onTodo%1$sd(const Todo todo) @safe
            {
                import std.algorithm.iteration : each;

                immutable todoChange = TodoNotification(TodoNotificationType.%1$s, todo);
                listeners.byKey.each!(listener => listener(todoChange));
            }
        }(method.to!string));
    }
}