// 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 "src/privet/publisher.h"

#include <map>

#include <weave/error.h>
#include <weave/provider/dns_service_discovery.h>

#include "src/privet/cloud_delegate.h"
#include "src/privet/device_delegate.h"
#include "src/privet/device_ui_kind.h"
#include "src/privet/wifi_bootstrap_manager.h"
#include "src/privet/wifi_ssid_generator.h"
#include "src/string_utils.h"

namespace weave {
namespace privet {

namespace {

// The service type we'll expose via DNS-SD.
const char kPrivetServiceType[] = "_privet._tcp";

}  // namespace

Publisher::Publisher(const DeviceDelegate* device,
                     const CloudDelegate* cloud,
                     const WifiDelegate* wifi,
                     provider::DnsServiceDiscovery* dns_sd)
    : dns_sd_{dns_sd}, device_{device}, cloud_{cloud}, wifi_{wifi} {
  CHECK(device_);
  CHECK(cloud_);
  CHECK(dns_sd_);
  Update();
}

Publisher::~Publisher() {
  RemoveService();
}

void Publisher::Update() {
  if (device_->GetHttpEnpoint().first == 0)
    return RemoveService();
  ExposeService();
}

void Publisher::ExposeService() {
  std::string name{cloud_->GetName()};
  std::string model_id{cloud_->GetModelId()};
  DCHECK_EQ(model_id.size(), 5U);

  VLOG(2) << "DNS-SD update requested";
  const uint16_t port = device_->GetHttpEnpoint().first;
  DCHECK_NE(port, 0);

  std::vector<std::string> txt_record{
      {"txtvers=3"},
      {"ty=" + name},
      {"services=" + GetDeviceUiKind(model_id)},
      {"id=" + cloud_->GetDeviceId()},
      {"mmid=" + model_id},
      {"flags=" + WifiSsidGenerator{cloud_, wifi_}.GenerateFlags()},
  };

  if (device_->GetHttpsEnpoint().first > 0)
    txt_record.emplace_back("https=" +
                            std::to_string(device_->GetHttpsEnpoint().first));

  if (!cloud_->GetCloudId().empty())
    txt_record.emplace_back("gcd_id=" + cloud_->GetCloudId());

  if (!cloud_->GetDescription().empty())
    txt_record.emplace_back("note=" + cloud_->GetDescription());

  auto new_data = std::make_pair(port, txt_record);
  if (published_ == new_data)
    return;

  VLOG(1) << "Updating service using DNS-SD, port: " << port;
  published_ = new_data;
  dns_sd_->PublishService(kPrivetServiceType, port, txt_record);
}

void Publisher::RemoveService() {
  if (!published_.first)
    return;
  published_ = {};
  VLOG(1) << "Stopping service publishing";
  dns_sd_->StopPublishing(kPrivetServiceType);
}

}  // namespace privet
}  // namespace weave
