// Copyright 2020 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/lib/paver/utils.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <fidl/fuchsia.hardware.block.partition/cpp/wire.h>
#include <fidl/fuchsia.hardware.skipblock/cpp/wire.h>
#include <fidl/fuchsia.sysinfo/cpp/wire.h>
#include <lib/fdio/cpp/caller.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/unsafe.h>
#include <lib/fdio/watcher.h>
#include <lib/service/llcpp/service.h>

#include <string_view>

#include <fbl/algorithm.h>
#include <gpt/gpt.h>

#include "src/lib/uuid/uuid.h"
#include "src/storage/lib/paver/partition-client.h"
#include "src/storage/lib/paver/pave-logging.h"

namespace paver {

namespace {

using uuid::Uuid;

namespace partition = fuchsia_hardware_block_partition;
namespace skipblock = fuchsia_hardware_skipblock;

}  // namespace

// Not static so test can manipulate it.
zx_duration_t g_wipe_timeout = ZX_SEC(3);

BlockWatcherPauser::~BlockWatcherPauser() {
  if (valid_) {
    auto result = watcher_->Resume();
    if (result.status() != ZX_OK) {
      ERROR("Failed to unpause the block watcher: %s\n", zx_status_get_string(result.status()));
    } else if (result.value().status != ZX_OK) {
      ERROR("Failed to unpause the block watcher: %s\n",
            zx_status_get_string(result.value().status));
    }
  }
}

zx::status<BlockWatcherPauser> BlockWatcherPauser::Create(
    fidl::UnownedClientEnd<fuchsia_io::Directory> svc_root) {
  auto local = service::ConnectAt<fuchsia_fshost::BlockWatcher>(svc_root);
  if (!local.is_ok()) {
    return local.take_error();
  }

  BlockWatcherPauser pauser(std::move(*local));
  if (auto status = pauser.Pause(); status.is_error()) {
    return status.take_error();
  }

  return zx::ok(std::move(pauser));
}

zx::status<> BlockWatcherPauser::Pause() {
  auto result = watcher_->Pause();
  auto status = zx::make_status(result.ok() ? result.value().status : result.status());

  valid_ = status.is_ok();
  return status;
}

zx::status<zx::channel> OpenPartition(const fbl::unique_fd& devfs_root, const char* path,
                                      fit::function<bool(const zx::channel&)> should_filter_file,
                                      zx_duration_t timeout) {
  ZX_ASSERT(path != nullptr);

  struct CallbackInfo {
    zx::channel out_partition;
    fit::function<bool(const zx::channel&)> should_filter_file;
  };

  CallbackInfo info = {
      .out_partition = zx::channel(),
      .should_filter_file = std::move(should_filter_file),
  };

  auto cb = [](int dirfd, int event, const char* filename, void* cookie) {
    if (event != WATCH_EVENT_ADD_FILE) {
      return ZX_OK;
    }
    if ((strcmp(filename, ".") == 0) || strcmp(filename, "..") == 0) {
      return ZX_OK;
    }
    fdio_cpp::UnownedFdioCaller caller(dirfd);

    zx::channel partition_local, partition_remote;
    if (zx::channel::create(0, &partition_local, &partition_remote) != ZX_OK) {
      return ZX_OK;
    }
    if (fdio_service_connect_at(caller.borrow_channel(), filename, partition_remote.release()) !=
        ZX_OK) {
      return ZX_OK;
    }
    auto info = static_cast<CallbackInfo*>(cookie);
    if (info->should_filter_file(partition_local)) {
      return ZX_OK;
    }
    info->out_partition = std::move(partition_local);
    return ZX_ERR_STOP;
  };

  fbl::unique_fd dir_fd(openat(devfs_root.get(), path, O_RDONLY));
  if (!dir_fd) {
    return zx::error(ZX_ERR_IO);
  }

  zx_time_t deadline = zx_deadline_after(timeout);
  if (fdio_watch_directory(dir_fd.get(), cb, deadline, &info) != ZX_ERR_STOP) {
    return zx::error(ZX_ERR_NOT_FOUND);
  }
  return zx::ok(std::move(info.out_partition));
}

constexpr char kBlockDevPath[] = "class/block/";

zx::status<fidl::ClientEnd<partition::Partition>> OpenBlockPartition(
    const fbl::unique_fd& devfs_root, std::optional<Uuid> unique_guid,
    std::optional<Uuid> type_guid, zx_duration_t timeout) {
  ZX_ASSERT(unique_guid || type_guid);

  auto cb = [&](const zx::channel& chan) {
    if (type_guid) {
      auto result = fidl::WireCall<partition::Partition>(zx::unowned(chan))->GetTypeGuid();
      if (!result.ok()) {
        return true;
      }
      auto& response = result.value();
      if (response.status != ZX_OK || type_guid != Uuid(response.guid->value.data())) {
        return true;
      }
    }
    if (unique_guid) {
      auto result = fidl::WireCall<partition::Partition>(zx::unowned(chan))->GetInstanceGuid();
      if (!result.ok()) {
        return true;
      }
      const auto& response = result.value();
      if (response.status != ZX_OK || unique_guid != Uuid(response.guid->value.data())) {
        return true;
      }
    }
    return false;
  };

  return OpenPartition(devfs_root, kBlockDevPath, cb, timeout);
}

constexpr char kSkipBlockDevPath[] = "class/skip-block/";

zx::status<fidl::ClientEnd<skipblock::SkipBlock>> OpenSkipBlockPartition(
    const fbl::unique_fd& devfs_root, const Uuid& type_guid, zx_duration_t timeout) {
  auto cb = [&](const zx::channel& chan) {
    auto result = fidl::WireCall<skipblock::SkipBlock>(zx::unowned(chan))->GetPartitionInfo();
    if (!result.ok()) {
      return true;
    }
    const auto& response = result.value();
    if (response.status != ZX_OK ||
        type_guid != Uuid(response.partition_info.partition_guid.data())) {
      return true;
    }
    return false;
  };

  return OpenPartition(devfs_root, kSkipBlockDevPath, cb, timeout);
}

bool HasSkipBlockDevice(const fbl::unique_fd& devfs_root) {
  // Our proxy for detected a skip-block device is by checking for the
  // existence of a device enumerated under the skip-block class.
  return OpenSkipBlockPartition(devfs_root, GUID_ZIRCON_A_VALUE, ZX_SEC(1)).is_ok();
}

// Attempts to open and overwrite the first block of the underlying
// partition. Does not rebind partition drivers.
//
// At most one of |unique_guid| and |type_guid| may be nullptr.
zx::status<> WipeBlockPartition(const fbl::unique_fd& devfs_root, std::optional<Uuid> unique_guid,
                                std::optional<Uuid> type_guid) {
  auto status = OpenBlockPartition(devfs_root, unique_guid, type_guid, g_wipe_timeout);
  if (status.is_error()) {
    ERROR("Warning: Could not open partition to wipe: %s\n", status.status_string());
    return status.take_error();
  }

  // Overwrite the first block to (hackily) ensure the destroyed partition
  // doesn't "reappear" in place.
  BlockPartitionClient block_partition(std::move(status.value()));
  auto status2 = block_partition.GetBlockSize();
  if (status2.is_error()) {
    ERROR("Warning: Could not get block size of partition: %s\n", status2.status_string());
    return status2.take_error();
  }
  const size_t block_size = status2.value();

  // Rely on vmos being 0 initialized.
  zx::vmo vmo;
  {
    auto status = zx::make_status(
        zx::vmo::create(fbl::round_up(block_size, zx_system_get_page_size()), 0, &vmo));
    if (status.is_error()) {
      ERROR("Warning: Could not create vmo: %s\n", status.status_string());
      return status.take_error();
    }
  }

  if (auto status = block_partition.Write(vmo, block_size); status.is_error()) {
    ERROR("Warning: Could not write to block device: %s\n", status.status_string());
    return status.take_error();
  }

  if (auto status = block_partition.Flush(); status.is_error()) {
    ERROR("Warning: Failed to synchronize block device: %s\n", status.status_string());
    return status.take_error();
  }

  return zx::ok();
}

zx::status<> IsBoard(const fbl::unique_fd& devfs_root, std::string_view board_name) {
  zx::channel local, remote;
  auto status = zx::make_status(zx::channel::create(0, &local, &remote));
  if (status.is_error()) {
    return status.take_error();
  }

  fdio_cpp::UnownedFdioCaller caller(devfs_root.get());
  status = zx::make_status(
      fdio_service_connect_at(caller.borrow_channel(), "sys/platform", remote.release()));
  if (status.is_error()) {
    return status.take_error();
  }

  auto result = fidl::WireCall<fuchsia_sysinfo::SysInfo>(zx::unowned(local))->GetBoardName();
  status = zx::make_status(result.ok() ? result.value().status : result.status());
  if (status.is_error()) {
    return status.take_error();
  }
  if (strncmp(result.value().name.data(), board_name.data(), result.value().name.size()) == 0) {
    return zx::ok();
  }

  return zx::error(ZX_ERR_NOT_SUPPORTED);
}

zx::status<> IsBootloader(const fbl::unique_fd& devfs_root, std::string_view vendor) {
  zx::channel local, remote;
  zx::status<> status = zx::make_status(zx::channel::create(0, &local, &remote));
  if (status.is_error()) {
    return status.take_error();
  }

  fdio_cpp::UnownedFdioCaller caller(devfs_root.get());
  status = zx::make_status(
      fdio_service_connect_at(caller.borrow_channel(), "sys/platform", remote.release()));
  if (status.is_error()) {
    return status.take_error();
  }

  auto result = fidl::WireCall<fuchsia_sysinfo::SysInfo>(zx::unowned(local))->GetBootloaderVendor();
  status = zx::make_status(result.ok() ? result.value().status : result.status());
  if (status.is_error()) {
    return status.take_error();
  }
  if (strncmp(result.value().vendor.data(), vendor.data(), result.value().vendor.size()) == 0) {
    return zx::ok();
  }

  return zx::error(ZX_ERR_NOT_SUPPORTED);
}
}  // namespace paver
