// Copyright 2019 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 "factory_reset.h"

#include <dirent.h>
#include <errno.h>
#include <fbl/string_buffer.h>
#include <fbl/string_piece.h>
#include <fbl/unique_ptr.h>
#include <fcntl.h>
#include <fs-management/mount.h>
#include <fuchsia/device/c/fidl.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <fuchsia/sysinfo/c/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/fzl/fdio.h>
#include <lib/zx/channel.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/system.h>

namespace factory_reset {

const char* kBlockPath = "class/block";
const int kNumZxcryptSuperblocks = 3;

zx_status_t WriteRandomBlock(int fd, ssize_t block_size) {
  std::unique_ptr<uint8_t[]> buf(new uint8_t[block_size]);
  zx_cprng_draw(buf.get(), block_size);
  ssize_t res;
  if ((res = write(fd, buf.get(), block_size)) < block_size) {
    fprintf(stderr, "write(%d, %p, %zu) failed: %s\n ", fd, buf.get(),
            block_size, strerror(errno));
    return ZX_ERR_IO;
  }
  return ZX_OK;
}

// Determines the block size of the passed in fd.
zx_status_t FindBlockSize(int fd, ssize_t* block_size) {
  zx_status_t rc, call_status;
  fzl::UnownedFdioCaller caller(fd);
  if (!caller) {
    return ZX_ERR_BAD_STATE;
  }
  fuchsia_hardware_block_BlockInfo block_info;
  if ((rc = fuchsia_hardware_block_BlockGetInfo(
           caller.borrow_channel(), &call_status, &block_info)) != ZX_OK) {
    return rc;
  }
  if (call_status != ZX_OK) {
    return call_status;
  }
  *block_size = block_info.block_size;
  return ZX_OK;
}

zx_status_t ShredBlockDevice(fbl::unique_fd fd, int num_blocks) {
  zx_status_t status;
  if (lseek(fd.get(), 0, SEEK_SET) != 0) {
    return ZX_ERR_IO;
  }

  ssize_t block_size = 0;
  status = FindBlockSize(fd.get(), &block_size);
  if (status != ZX_OK) {
    return status;
  }

  for (int i = 0; i < num_blocks; ++i) {
    if ((status = WriteRandomBlock(fd.get(), block_size)) != ZX_OK) {
      fprintf(stderr, "Couldn't write to %d block: %d (%s)\n", i, status,
              zx_status_get_string(status));
      return status;
    }
  }
  return ZX_OK;
}

FactoryReset::FactoryReset(fbl::unique_fd dev_fd,
                           fuchsia::device::manager::AdministratorPtr admin) {
  dev_fd_ = std::move(dev_fd);
  admin_ = std::move(admin);
}

zx_status_t FactoryReset::Shred() const {
  fbl::unique_fd block_dir(
      openat(dev_fd_.get(), kBlockPath, O_RDONLY | O_DIRECTORY));
  if (!block_dir) {
    fprintf(stderr, "Error opening %s\n", kBlockPath);
    return ZX_ERR_NOT_FOUND;
  }
  struct dirent* de;
  DIR* dir = fdopendir(block_dir.get());
  // Attempts to shred every zxcrypt volume found.
  while ((de = readdir(dir)) != nullptr) {
    fbl::unique_fd block_fd(openat(dirfd(dir), de->d_name, O_RDWR));
    if (!block_fd ||
        detect_disk_format(block_fd.get()) != DISK_FORMAT_ZXCRYPT) {
      continue;
    }
    zx_status_t status =
        ShredBlockDevice(std::move(block_fd), kNumZxcryptSuperblocks);
    if (status != ZX_OK) {
      return status;
    }
  }
  return ZX_OK;
}

void FactoryReset::Reset(ResetCallback callback) {
  zx_status_t status = Shred();
  if (status != ZX_OK) {
    fprintf(stderr, "FactoryReset: Shred failed: %d (%s)\n", status, zx_status_get_string(status));
    callback(std::move(status));
    return;
  }

  // Reboot to initiate the recovery.
  admin_->Suspend(fuchsia::device::manager::SUSPEND_FLAG_REBOOT,
                  std::move(callback));
}

}  // namespace factory_reset
