// Copyright 2017 The Fuchsia 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 "peridot/bin/sessionmgr/device_map_impl.h"

#include <limits.h>
#include <unistd.h>

#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_ptr.h>
#include <lib/fidl/cpp/optional.h>
#include <src/lib/fxl/time/time_point.h>

#include "peridot/bin/sessionmgr/storage/constants_and_utils.h"
#include "peridot/lib/fidl/json_xdr.h"
#include "peridot/lib/ledger_client/operations.h"

namespace modular {

namespace {

using ReadDeviceDataCall = ReadDataCall<fuchsia::modular::DeviceMapEntry>;
using ReadAllDeviceDataCall = ReadAllDataCall<fuchsia::modular::DeviceMapEntry>;
using WriteDeviceDataCall = WriteDataCall<fuchsia::modular::DeviceMapEntry>;

// Reads old versions of device data, which are missing a timestamp.
void XdrDeviceMapEntry_v1(XdrContext* const xdr,
                          fuchsia::modular::DeviceMapEntry* const data) {
  xdr->Field("name", &data->name);
  xdr->Field("device_id", &data->device_id);
  xdr->Field("profile", &data->profile);
  xdr->Field("hostname", &data->hostname);

  // The time below is 26 Sep 2017 17:44:40 GMT, just to mark the entry as old.
  // Since this filter is not the latest, it is only ever used FROM_JSON, never
  // TO_JSON.
  data->last_change_timestamp = 1506447879;
}

void XdrDeviceMapEntry_v2(XdrContext* const xdr,
                          fuchsia::modular::DeviceMapEntry* const data) {
  xdr->Field("name", &data->name);
  xdr->Field("device_id", &data->device_id);
  xdr->Field("profile", &data->profile);
  xdr->Field("hostname", &data->hostname);
  xdr->Field("last_change_timestamp", &data->last_change_timestamp);
}

void XdrDeviceMapEntry_v3(XdrContext* const xdr,
                          fuchsia::modular::DeviceMapEntry* const data) {
  if (!xdr->Version(3)) {
    return;
  }
  xdr->Field("name", &data->name);
  xdr->Field("device_id", &data->device_id);
  xdr->Field("profile", &data->profile);
  xdr->Field("hostname", &data->hostname);
  xdr->Field("last_change_timestamp", &data->last_change_timestamp);
}

constexpr XdrFilterType<fuchsia::modular::DeviceMapEntry> XdrDeviceMapEntry[] =
    {
        XdrDeviceMapEntry_v3,
        XdrDeviceMapEntry_v2,
        XdrDeviceMapEntry_v1,
        nullptr,
};

std::string LoadHostname() {
  char host_name_buffer[HOST_NAME_MAX + 1];
  int result = gethostname(host_name_buffer, sizeof(host_name_buffer));

  if (result < 0) {
    FXL_LOG(ERROR) << "unable to get hostname. errno " << errno;
    return "fuchsia";
  }

  return host_name_buffer;
}

}  // namespace

DeviceMapImpl::DeviceMapImpl(const std::string& device_name,
                             const std::string& device_id,
                             const std::string& device_profile,
                             LedgerClient* const ledger_client,
                             LedgerPageId page_id)
    : PageClient("DeviceMapImpl", ledger_client, std::move(page_id),
                 kDeviceKeyPrefix) {
  current_device_id_ = device_id;

  // TODO(jimbe) Load the fuchsia::modular::DeviceMapEntry for the current
  // device from the Ledger.
  fuchsia::modular::DeviceMapEntry device;
  device.name = device_name;
  device.device_id = device_id;
  device.profile = device_profile;
  device.hostname = LoadHostname();

  devices_[device_id] = std::move(device);
  SaveCurrentDevice();
}

DeviceMapImpl::~DeviceMapImpl() = default;

void DeviceMapImpl::Connect(
    fidl::InterfaceRequest<fuchsia::modular::DeviceMap> request) {
  bindings_.AddBinding(this, std::move(request));
}

void DeviceMapImpl::Query(QueryCallback callback) {
  operation_queue_.Add(std::make_unique<ReadAllDeviceDataCall>(
      page(), kDeviceKeyPrefix, XdrDeviceMapEntry, std::move(callback)));
}

void DeviceMapImpl::GetCurrentDevice(GetCurrentDeviceCallback callback) {
  callback(devices_[current_device_id_]);
}

void DeviceMapImpl::SetCurrentDeviceProfile(::std::string profile) {
  devices_[current_device_id_].profile = profile;
  Notify(current_device_id_);
  SaveCurrentDevice();
}

void DeviceMapImpl::SaveCurrentDevice() {
  auto& device = devices_[current_device_id_];
  device.last_change_timestamp = time(nullptr);

  operation_queue_.Add(std::make_unique<WriteDeviceDataCall>(
      page(), MakeDeviceKey(current_device_id_), XdrDeviceMapEntry,
      fidl::MakeOptional(device), [] {}));
}

void DeviceMapImpl::WatchDeviceMap(
    fidl::InterfaceHandle<fuchsia::modular::DeviceMapWatcher> watcher) {
  auto watcher_ptr = watcher.Bind();
  for (const auto& item : devices_) {
    const auto& device = item.second;
    watcher_ptr->OnDeviceMapChange(device);
  }
  change_watchers_.AddInterfacePtr(std::move(watcher_ptr));
}

void DeviceMapImpl::Notify(const std::string& device_id) {
  const fuchsia::modular::DeviceMapEntry& device = devices_[current_device_id_];
  for (auto& watcher : change_watchers_.ptrs()) {
    (*watcher)->OnDeviceMapChange(device);
  }
}

void DeviceMapImpl::OnPageChange(const std::string& key,
                                 const std::string& value) {
  FXL_LOG(INFO) << "Updated Device: " << key << " value=" << value;

  fuchsia::modular::DeviceMapEntry device;
  if (!XdrRead(value, &device, XdrDeviceMapEntry)) {
    FXL_DCHECK(false);
    return;
  }

  fidl::StringPtr device_id = device.device_id;
  devices_[device_id] = std::move(device);
  Notify(device_id);
}

void DeviceMapImpl::OnPageDelete(const std::string& key) {
  // This shouldn't happen.
  FXL_LOG(ERROR) << "Deleted Device: " << key;
}

}  // namespace modular
