// Copyright 2015 The Weave Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "examples/provider/avahi_client.h"

#include <cstdlib>
#include <vector>

#include <avahi-common/error.h>

namespace weave {
namespace examples {

namespace {

void GroupCallback(AvahiEntryGroup* g,
                   AvahiEntryGroupState state,
                   AVAHI_GCC_UNUSED void* userdata) {
  CHECK_NE(state, AVAHI_ENTRY_GROUP_COLLISION);
  CHECK_NE(state, AVAHI_ENTRY_GROUP_FAILURE);
}

std::string GetId() {
  return "WEAVE" + std::to_string(gethostid());
}

}  // namespace

AvahiClient::AvahiClient() {
  thread_pool_.reset(avahi_threaded_poll_new());
  CHECK(thread_pool_);

  LOG(INFO) << "connecting to avahi-daemon";
  int ret = 0;
  client_.reset(avahi_client_new(avahi_threaded_poll_get(thread_pool_.get()),
                                 {}, nullptr, this, &ret));
  CHECK(client_) << avahi_strerror(ret);

  avahi_threaded_poll_start(thread_pool_.get());

  group_.reset(avahi_entry_group_new(client_.get(), GroupCallback, nullptr));
  CHECK(group_) << avahi_strerror(avahi_client_errno(client_.get()))
                << ". Check avahi-daemon configuration";
}

AvahiClient::~AvahiClient() {
  if (thread_pool_)
    avahi_threaded_poll_stop(thread_pool_.get());
}

void AvahiClient::PublishService(const std::string& service_type,
                                 uint16_t port,
                                 const std::vector<std::string>& txt) {
  LOG(INFO) << "Publishing service";
  CHECK(group_);

  // Create txt record.
  std::unique_ptr<AvahiStringList, decltype(&avahi_string_list_free)> txt_list{
      nullptr, &avahi_string_list_free};
  if (!txt.empty()) {
    std::vector<const char*> txt_vector_ptr;
    for (const auto& i : txt)
      txt_vector_ptr.push_back(i.c_str());
    txt_list.reset(avahi_string_list_new_from_array(txt_vector_ptr.data(),
                                                    txt_vector_ptr.size()));
    CHECK(txt_list);
  }

  int ret = 0;
  if (prev_port_ == port && prev_type_ == service_type) {
    ret = avahi_entry_group_update_service_txt_strlst(
        group_.get(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, {}, GetId().c_str(),
        service_type.c_str(), nullptr, txt_list.get());
    CHECK_GE(ret, 0) << avahi_strerror(ret);
  } else {
    prev_port_ = port;
    prev_type_ = service_type;

    avahi_entry_group_reset(group_.get());
    CHECK(avahi_entry_group_is_empty(group_.get()));

    ret = avahi_entry_group_add_service_strlst(
        group_.get(), AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, {}, GetId().c_str(),
        service_type.c_str(), nullptr, nullptr, port, txt_list.get());
    CHECK_GE(ret, 0) << avahi_strerror(ret);
    ret = avahi_entry_group_commit(group_.get());
    CHECK_GE(ret, 0) << avahi_strerror(ret);
  }
}

void AvahiClient::StopPublishing(const std::string& service_name) {
  CHECK(group_);
  avahi_entry_group_reset(group_.get());
}

}  // namespace examples
}  // namespace weave
