// Copyright 2021 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 "src/storage/fshost/watcher.h"

#include <fcntl.h>
#include <lib/syslog/cpp/macros.h>

#include "src/storage/fshost/block-device-manager.h"
#include "src/storage/fshost/filesystem-mounter.h"
#include "src/storage/fshost/nand-device.h"

namespace fshost {
namespace {
namespace fio = fuchsia_io;

template <typename T>
zx_status_t AddDeviceImpl(BlockDeviceManager& manager, FilesystemMounter* mounter,
                          fbl::unique_fd fd) {
  T device(mounter, std::move(fd), manager.config());
  return manager.AddDevice(device);
}

}  // namespace

std::vector<Watcher> Watcher::CreateWatchers() {
  std::pair<const char*, AddDeviceCallback> types[] = {
      {"/dev/class/block", AddDeviceImpl<BlockDevice>},
      {"/dev/class/nand", AddDeviceImpl<NandDevice>},
  };
  std::vector<Watcher> ret;
  for (auto& [path, callback] : types) {
    fbl::unique_fd dirfd(open(path, O_DIRECTORY | O_RDONLY));
    if (!dirfd) {
      FX_LOGS(ERROR) << "failed to open " << path << ": " << strerror(errno);
      continue;
    }

    fdio_cpp::FdioCaller caller(std::move(dirfd));

    ret.emplace_back(Watcher(path, std::move(caller), std::move(callback)));
  }

  return ret;
}

zx_status_t Watcher::ReinitWatcher() {
  watcher_.reset();
  zx::status server_end = fidl::CreateEndpoints<fio::DirectoryWatcher>(&watcher_);
  if (server_end.is_error()) {
    FX_PLOGS(ERROR, server_end.status_value()) << "failed to create watcher channel";
    return server_end.status_value();
  }

  auto mask = fio::wire::WatchMask::kMask;
  if (ignore_existing_) {
    mask &= ~fio::wire::WatchMask::kExisting;
  }
  auto result = fidl::WireCall(caller_.borrow_as<fio::Directory>())
                    ->Watch(mask, 0, std::move(server_end.value()));
  if (!result.ok()) {
    FX_LOGS(ERROR) << "failed to send watch: " << result.error();
    return result.status();
  }
  if (result.value().s != ZX_OK) {
    FX_LOGS(ERROR) << "watch failed: " << zx_status_get_string(result.value().s);
    return result.value().s;
  }

  return ZX_OK;
}

void Watcher::ProcessWatchMessages(cpp20::span<uint8_t> buf, WatcherCallback callback) {
  uint8_t* iter = buf.begin();
  while (iter + 2 <= buf.end()) {
    fio::wire::WatchEvent event = static_cast<fio::wire::WatchEvent>(*iter++);
    uint8_t name_len = *iter++;

    if (iter + name_len > buf.end()) {
      break;
    }

    // Save the first byte of the next message,
    // and null-terminate the name.
    uint8_t tmp = iter[name_len];
    iter[name_len] = 0;

    if (callback(*this, caller_.fd().get(), event, reinterpret_cast<const char*>(iter))) {
      // We received a WATCH_EVENT_IDLE, and the watcher is paused.
      // Bail out early.
      ignore_existing_ = true;
      return;
    }
    if (event == fio::wire::WatchEvent::kIdle) {
      // WATCH_EVENT_IDLE - but the watcher is not paused. Finish processing this set of messages,
      // but set ignore_existing_ to indicate that we should start checking for the pause signal.
      ignore_existing_ = true;
      break;
    }

    iter[name_len] = tmp;

    iter += name_len;
  }
}

zx_status_t Watcher::AddDevice(BlockDeviceManager& manager, FilesystemMounter* mounter,
                               fbl::unique_fd fd) {
  return add_device_(manager, mounter, std::move(fd));
}

}  // namespace fshost
