/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

#include "./cfollower.h"

#include <string>

#include "../follower.hpp"
#include "../shtype/shtype-from-gst-caps.hpp"

namespace sh4lt {
class CFollower {
 public:
  CFollower(const char* path,
            void (*on_data_cb)(void* user_data, void* data, size_t size, const sh4lt_time_info_t*),
            void (*on_server_connected)(void* user_data, const char* type_descr),
            void (*on_server_disconnected)(void* user_data),
            void* user_data,
            Sh4ltLogger log)
      : on_data_cb_(on_data_cb),
        on_server_connected_(on_server_connected),
        on_server_disconnected_(on_server_disconnected),
        user_data_(user_data),
        follower_(
            path,
            [&](void* data, size_t size, const sh4lt_time_info_t* time_info) {
              if (nullptr != on_data_cb_) on_data_cb_(user_data_, data, size, time_info);
            },
            [&](const ShType& type_descr) {
              if (nullptr != on_server_connected_)
                on_server_connected_(user_data_, shtype::shtype_to_gst_caps(type_descr).c_str());
            },
            [&]() {
              if (nullptr != on_server_disconnected_) on_server_disconnected_(user_data_);
            },
            (*static_cast<logger::Logger::ptr*>(log))) {}

 private:
  void (*on_data_cb_)(void* user_data, void* data, size_t size, const sh4lt_time_info_t*);
  void (*on_server_connected_)(void* user_data, const char* type_descr);
  void (*on_server_disconnected_)(void* user_data);
  void* user_data_;

 public:
  Follower follower_;
};
}  // namespace sh4lt

Sh4ltFollower sh4lt_make_follower(
    const char* path,
    void (*on_data_cb)(void* user_data, void* data, size_t size, const sh4lt_time_info_t* timeinfo),
    void (*on_server_connected)(void* user_data, const char* type_descr),
    void (*on_server_disconnected)(void* user_data),
    void* user_data,
    Sh4ltLogger log) {
  return static_cast<void*>(new sh4lt::CFollower(
      path, on_data_cb, on_server_connected, on_server_disconnected, user_data, log));
}

void sh4lt_set_monitor_relaunch(Sh4ltFollower follower, int relaunch) {
  static_cast<sh4lt::CFollower*>(follower)->follower_.set_monitor_relaunch(relaunch);
}

void sh4lt_delete_follower(Sh4ltFollower follower) {
  delete static_cast<sh4lt::CFollower*>(follower);
}
