// This file was generated automatically by Qleany's generator, edit at your own risk! 
// If you do, be careful to not overwrite it when you run the generator again.
#pragma once

#include "{{ export_header_file }}"
#include "event_dispatcher.h"
#include <qleany/contracts/repository/interface_repository_provider.h>
{% if feature.crud.enabled -%}
#include "{{ feature_name_snake }}/{{ entity_name_snake }}_dto.h"
    {% if feature.crud.get_with_details -%}
#include "{{ feature_name_snake }}/{{ entity_name_snake }}_with_details_dto.h"
    {% endif -%}
    {% if feature.crud.create -%}
#include "{{ feature_name_snake }}/create_{{ entity_name_snake }}_dto.h"
    {% endif -%}
    {% if feature.crud.update -%}
#include "{{ feature_name_snake }}/update_{{ entity_name_snake }}_dto.h"
    {% endif -%}
{% endif -%}
{% for command in feature.custom_commands -%}
{% if command.dto_in_enabled %}#include "{{ feature_name_snake }}/{{ command.dto_in_snake }}_dto.h"{% endif %}
{% if command.dto_out_enabled %}#include "{{ feature_name_snake }}/{{ command.dto_out_snake }}_dto.h"{% endif %}
{% endfor %}
{% for query in feature.custom_queries -%}
{% if query.dto_in_enabled %}#include "{{ feature_name_snake }}/{{ query.dto_in_snake }}_dto.h"{% endif %}
{% if query.dto_out_enabled %}#include "{{ feature_name_snake }}/{{ query.dto_out_snake }}_dto.h"{% endif %}
{% endfor -%}
#include <qleany/tools/undo_redo/threaded_undo_redo_system.h>
#include <QCoroTask>
#include <QObject>
#include <QSharedPointer>
#include <QPointer>

using namespace Qleany::Contracts::Repository;
using namespace Qleany::Tools::UndoRedo;
using namespace {{ application_cpp_domain_name }}::Contracts::DTO::{{ feature_name_pascal }};

namespace {{ application_cpp_domain_name }}::Controller::{{ feature_name_pascal }}
{

class {{ export }} {{ feature_name_pascal }}Controller : public QObject
{
    Q_OBJECT
  public:
    explicit {{ feature_name_pascal }}Controller(InterfaceRepositoryProvider *repositoryProvider,
                                 ThreadedUndoRedoSystem *undo_redo_system,
                                 QSharedPointer<EventDispatcher> eventDispatcher);

    static {{ feature_name_pascal }}Controller *instance();

{% if feature.crud.enabled %}
    {%if feature.crud.get %}
    Q_INVOKABLE QCoro::Task<{{ entity_name_pascal }}DTO> get(int id) const;
    {% endif %}
    {%if feature.crud.get_with_details %}
    Q_INVOKABLE QCoro::Task<{{ entity_name_pascal }}WithDetailsDTO>  getWithDetails(int id) const;
    {% endif %}
    {%if feature.crud.get_all %}
    Q_INVOKABLE QCoro::Task<QList<{{ entity_name_pascal }}DTO>> getAll() const;
    {% endif %}
{% endif %}

    {% for query in feature.custom_queries %}
    Q_INVOKABLE QCoro::Task<{{ query.dto_out }}DTO> {{ query.name_camel }}({% if query.dto_in_enabled %}{{ query.dto_in }}DTO dto{% endif %}) const;
    {% endfor %}

{% if feature.crud.enabled %}
    {% if feature.crud.create %}
    Q_INVOKABLE static Contracts::DTO::{{ entity_name_pascal }}::Create{{ entity_name_pascal }}DTO getCreateDTO();
    {% endif %}
    {% if feature.crud.update %}
    Q_INVOKABLE static Contracts::DTO::{{ entity_name_pascal }}::Update{{ entity_name_pascal }}DTO getUpdateDTO();
    {% endif %}
{% endif %}

  public slots:

{% if feature.crud.enabled %}
    {%if feature.crud.create %}
    QCoro::Task<{{ entity_name_pascal }}DTO> create(const Create{{ entity_name_pascal }}DTO &dto);
    {% endif %}
    {%if feature.crud.update %}
    QCoro::Task<{{ entity_name_pascal }}DTO> update(const Update{{ entity_name_pascal }}DTO &dto);
    {% endif %}
    {%if feature.crud.remove %}
    QCoro::Task<bool> remove(int id);
    {% endif %}

{% endif %}

    {% for command in feature.custom_commands %}
    QCoro::Task<{% if command.dto_out_enabled %}{{ command.dto_out }}DTO{% endif %}> {{ command.name_camel }}({% if command.dto_in_enabled %}{{ command.dto_in }}DTO dto{% endif %});
    {% endfor %}

  private:
    static QPointer<{{ feature_name_pascal }}Controller> s_instance;
    InterfaceRepositoryProvider *m_repositoryProvider;
    ThreadedUndoRedoSystem *m_undo_redo_system;
    QSharedPointer<EventDispatcher> m_eventDispatcher;
    {{ feature_name_pascal }}Controller() = delete;
    {{ feature_name_pascal }}Controller(const {{ feature_name_pascal }}Controller &) = delete;
    {{ feature_name_pascal }}Controller &operator=(const {{ feature_name_pascal }}Controller &) = delete;
};

} // namespace {{ application_cpp_domain_name }}::Controller::{{ feature_name_pascal }}
