#include "pistache/endpoint.h"
#include "pistache/http.h"
#include "pistache/router.h"
#ifdef __linux__
#include <vector>
#include <signal.h>
#include <unistd.h>
#endif

#include "IndividualSubscriptionDocumentApiImpl.h"
#include "IndividualUeContextDocumentApiImpl.h"
#include "N1N2IndividualSubscriptionDocumentApiImpl.h"
#include "N1N2MessageCollectionDocumentApiImpl.h"
#include "N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl.h"
#include "NonUEN2MessageNotificationIndividualSubscriptionDocumentApiImpl.h"
#include "NonUEN2MessagesCollectionDocumentApiImpl.h"
#include "NonUEN2MessagesSubscriptionsCollectionDocumentApiImpl.h"
#include "SubscriptionsCollectionDocumentApiImpl.h"

#define PISTACHE_SERVER_THREADS     2
#define PISTACHE_SERVER_MAX_PAYLOAD 32768

#include "amf_app.hpp"

using namespace oai::amf::api;

class AMFApiServer{
public:
  AMFApiServer(Pistache::Address address, amf_application::amf_app *amf_app_inst) : m_httpEndpoint(std::make_shared<Pistache::Http::Endpoint>(address)){
    m_router = std::make_shared<Pistache::Rest::Router>();
    m_individualSubscriptionDocumentApiImpl = std::make_shared<IndividualSubscriptionDocumentApiImpl> (m_router, amf_app_inst);
    m_individualUeContextDocumentApiImpl = std::make_shared<IndividualUeContextDocumentApiImpl>(m_router, amf_app_inst);
    m_n1N2IndividualSubscriptionDocumentApiImpl = std::make_shared<N1N2IndividualSubscriptionDocumentApiImpl>(m_router, amf_app_inst);
    m_n1N2MessageCollectionDocumentApiImpl = std::make_shared<N1N2MessageCollectionDocumentApiImpl>(m_router, amf_app_inst);
    m_n1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl = std::make_shared<N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl>(m_router, amf_app_inst);
    m_nonUEN2MessageNotificationIndividualSubscriptionDocumentApiImpl= std::make_shared<NonUEN2MessageNotificationIndividualSubscriptionDocumentApiImpl>(m_router, amf_app_inst);
    m_nonUEN2MessagesCollectionDocumentApiImpl = std::make_shared<NonUEN2MessagesCollectionDocumentApiImpl>(m_router, amf_app_inst);
    m_nonUEN2MessagesSubscriptionsCollectionDocumentApiImpl = std::make_shared<NonUEN2MessagesSubscriptionsCollectionDocumentApiImpl>(m_router, amf_app_inst);
    m_subscriptionsCollectionDocumentApiImpl = std::make_shared<SubscriptionsCollectionDocumentApiImpl>(m_router, amf_app_inst);
  }

  void init(size_t thr = 1);
  void start();
  void shutdown();  

private:
  std::shared_ptr<Pistache::Http::Endpoint> m_httpEndpoint;
  std::shared_ptr<Pistache::Rest::Router> m_router;
  std::shared_ptr<IndividualSubscriptionDocumentApiImpl> m_individualSubscriptionDocumentApiImpl;
  std::shared_ptr<IndividualUeContextDocumentApiImpl> m_individualUeContextDocumentApiImpl;
  std::shared_ptr<N1N2IndividualSubscriptionDocumentApiImpl> m_n1N2IndividualSubscriptionDocumentApiImpl;
  std::shared_ptr<N1N2MessageCollectionDocumentApiImpl> m_n1N2MessageCollectionDocumentApiImpl;
  std::shared_ptr<N1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl> m_n1N2SubscriptionsCollectionForIndividualUEContextsDocumentApiImpl;
  std::shared_ptr<NonUEN2MessageNotificationIndividualSubscriptionDocumentApiImpl> m_nonUEN2MessageNotificationIndividualSubscriptionDocumentApiImpl;
  std::shared_ptr<NonUEN2MessagesCollectionDocumentApiImpl> m_nonUEN2MessagesCollectionDocumentApiImpl;
  std::shared_ptr<NonUEN2MessagesSubscriptionsCollectionDocumentApiImpl> m_nonUEN2MessagesSubscriptionsCollectionDocumentApiImpl;
  std::shared_ptr<SubscriptionsCollectionDocumentApiImpl> m_subscriptionsCollectionDocumentApiImpl;
};
