// Copyright 2016 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/lib/fsl/io/device_watcher.h"

#include <lib/async/default.h>
#include <lib/component/incoming/cpp/protocol.h>
#include <lib/syslog/cpp/macros.h>

#include <utility>

namespace fio = fuchsia_io;

namespace fsl {

DeviceWatcher::DeviceWatcher(async_dispatcher_t* dispatcher,
                             fidl::ClientEnd<fuchsia_io::Directory> dir,
                             fidl::Endpoints<fuchsia_io::DirectoryWatcher> dir_watcher,
                             ExistsCallback exists_callback, IdleCallback idle_callback)
    : dir_watcher_(std::move(dir_watcher.client)),
      exists_callback_(std::move(exists_callback)),
      idle_callback_(std::move(idle_callback)),
      wait_(this, dir_watcher_.channel().get(), ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED),
      weak_ptr_factory_(this) {
  if (dispatcher == nullptr) {
    dispatcher = async_get_default_dispatcher();
  }
  fidl::WireClient<fuchsia_io::Directory> client(std::move(dir), dispatcher);
  client
      ->Watch(fio::wire::WatchMask::kAdded | fio::wire::WatchMask::kExisting |
                  fio::wire::WatchMask::kIdle,
              0, std::move(dir_watcher.server))
      .Then([client = std::move(client), weak = weak_ptr_factory_.GetWeakPtr(), dispatcher](
                const fidl::WireUnownedResult<fuchsia_io::Directory::Watch>& result) mutable {
        if (!result.ok()) {
          if (!result.is_dispatcher_shutdown()) {
            FX_PLOGS(ERROR, result.status()) << "Failed to create device watcher";
          }
          return;
        }
        const fidl::WireResponse response = result.value();
        if (response.s != ZX_OK) {
          FX_PLOGS(ERROR, response.s) << "Failed to create device watcher";
          return;
        }
        fit::result dir = client.UnbindMaybeGetEndpoint();
        if (dir.is_error()) {
          FX_LOGS(ERROR) << "Failed to unbind directory client "
                         << dir.error_value().FormatDescription();
          return;
        }
        DeviceWatcher* self = weak.get();
        if (self == nullptr) {
          return;
        }
        self->dir_ = std::move(dir.value());
        zx_status_t status = self->wait_.Begin(dispatcher);
        FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
      });
}

std::unique_ptr<DeviceWatcher> DeviceWatcher::Create(const std::string& directory_path,
                                                     ExistsCallback exists_callback,
                                                     async_dispatcher_t* dispatcher) {
  return CreateWithIdleCallback(
      directory_path, std::move(exists_callback), [] {}, dispatcher);
}

std::unique_ptr<DeviceWatcher> DeviceWatcher::CreateWithIdleCallback(
    const std::string& directory_path, ExistsCallback exists_callback, IdleCallback idle_callback,
    async_dispatcher_t* dispatcher) {
  zx::result dir = component::OpenServiceRoot(directory_path);
  if (dir.is_error()) {
    FX_PLOGS(ERROR, dir.error_value()) << "Failed to open " << directory_path;
    return nullptr;
  }
  return CreateWithIdleCallback(std::move(dir.value()), std::move(exists_callback),
                                std::move(idle_callback), dispatcher);
}

std::unique_ptr<DeviceWatcher> DeviceWatcher::CreateWithIdleCallback(
    fidl::ClientEnd<fuchsia_io::Directory> dir, ExistsCallback exists_callback,
    IdleCallback idle_callback, async_dispatcher_t* dispatcher) {
  zx::result endpoints = fidl::CreateEndpoints<fio::DirectoryWatcher>();
  if (endpoints.is_error()) {
    return nullptr;
  }
  return std::unique_ptr<DeviceWatcher>(
      new DeviceWatcher(dispatcher, std::move(dir), std::move(endpoints.value()),
                        std::move(exists_callback), std::move(idle_callback)));
}

void DeviceWatcher::Handler(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                            zx_status_t status, const zx_packet_signal* signal) {
  if (status != ZX_OK)
    return;

  if (signal->observed & ZX_CHANNEL_READABLE) {
    uint32_t size;
    uint8_t buf[fio::wire::kMaxBuf];
    zx_status_t status =
        dir_watcher_.channel().read(0, buf, nullptr, sizeof(buf), 0, &size, nullptr);
    FX_CHECK(status == ZX_OK) << zx_status_get_string(status);

    auto weak = weak_ptr_factory_.GetWeakPtr();
    uint8_t* msg = buf;
    while (size >= 2) {
      fio::wire::WatchEvent event = static_cast<fio::wire::WatchEvent>(*msg++);
      unsigned namelen = *msg++;
      if (size < (namelen + 2u)) {
        break;
      }
      if ((event == fio::wire::WatchEvent::kAdded) || (event == fio::wire::WatchEvent::kExisting)) {
        std::string filename(reinterpret_cast<char*>(msg), namelen);
        // "." is not a device, so ignore it.
        if (filename != ".") {
          exists_callback_(dir_, filename);
        }
      } else if (event == fio::wire::WatchEvent::kIdle) {
        idle_callback_();
        // Only call the idle callback once.  In case there is some captured
        // context, remove the function, or rather set it to an empty function,
        // in case we try to call it again.
        idle_callback_ = [] {};
      }
      // Note: Callback may have destroyed the DeviceWatcher before returning.
      if (!weak) {
        return;
      }
      msg += namelen;
      size -= namelen + 2;
    }
    wait->Begin(dispatcher);  // ignore errors
    return;
  }

  if (signal->observed & ZX_CHANNEL_PEER_CLOSED) {
    // TODO(jeffbrown): Should we tell someone about this?
    dir_watcher_.reset();
    return;
  }

  FX_CHECK(false);
}

}  // namespace fsl
