//
//  mdns_client.hpp
//
//  Copyright (c) 2019 2020 Andrea Bondavalli. All rights reserved.
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  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 General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see .
//
#ifndef _MDNS_CLIENT_HPP_
#define _MDNS_CLIENT_HPP_
#ifdef _USE_AVAHI_
#include 
#include 
#include 
#include 
#include 
#endif
#include 
#include 
#include 
#include 
#include 
#include "config.hpp"
#include "rtsp_client.hpp"
class MDNSClient {
 public:
  explicit MDNSClient(std::shared_ptr config) : config_(config){};
  MDNSClient() = delete;
  MDNSClient(const MDNSClient&) = delete;
  MDNSClient& operator=(const MDNSClient&) = delete;
  virtual ~MDNSClient() = default;
  virtual bool init();
  virtual bool terminate();
 protected:
  virtual void on_change_rtsp_source(const std::string& name,
                                     const std::string& domain,
                                     const RtspSource& source){};
  virtual void on_remove_rtsp_source(const std::string& name,
                                     const std::string& domain){};
#ifdef _USE_AVAHI_
  static void resolve_callback(AvahiServiceResolver* r,
                               AvahiIfIndex interface,
                               AvahiProtocol protocol,
                               AvahiResolverEvent event,
                               const char* name,
                               const char* type,
                               const char* domain,
                               const char* host_name,
                               const AvahiAddress* address,
                               uint16_t port,
                               AvahiStringList* txt,
                               AvahiLookupResultFlags flags,
                               void* userdata);
  static void browse_callback(AvahiServiceBrowser* b,
                              AvahiIfIndex interface,
                              AvahiProtocol protocol,
                              AvahiBrowserEvent event,
                              const char* name,
                              const char* type,
                              const char* domain,
                              AvahiLookupResultFlags flags,
                              void* userdata);
  static void client_callback(AvahiClient* c,
                              AvahiClientState state,
                              void* userdata);
#endif
  void process_results();
  std::shared_ptr config_;
 private:
  std::list > sources_res_;
  std::mutex sources_res_mutex_;
  std::atomic_bool running_{false};
#ifdef _USE_AVAHI_
  /* order is important here */
  std::unique_ptr poll_{
      nullptr, &avahi_threaded_poll_free};
  std::unique_ptr client_{
      nullptr, &avahi_client_free};
  std::unique_ptr
      sb_{nullptr, &avahi_service_browser_free};
  std::set >
      active_resolvers;
#endif
};
#endif