// Copyright 2022 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 <fcntl.h>
#include <fidl/fuchsia.feedback.testing/cpp/wire.h>
#include <lib/fdio/vfs.h>
#include <lib/service/llcpp/service.h>
#include <lib/zx/vmo.h>
#include <unistd.h>

#include <cerrno>

#include <fbl/unique_fd.h>
#include <gtest/gtest.h>

#include "src/lib/storage/fs_management/cpp/admin.h"
#include "src/lib/storage/fs_management/cpp/format.h"
#include "src/lib/storage/fs_management/cpp/launch.h"
#include "src/lib/storage/fs_management/cpp/mount.h"
#include "src/lib/storage/fs_management/cpp/options.h"
#include "src/storage/fshost/block-device-manager.h"
#include "src/storage/fshost/block-device.h"
#include "src/storage/fshost/config.h"
#include "src/storage/fshost/constants.h"
#include "src/storage/fshost/testing/fshost_integration_test.h"
#include "src/storage/lib/utils/topological_path.h"
#include "src/storage/minfs/format.h"
#include "src/storage/testing/fvm.h"
#include "src/storage/testing/ram_disk.h"
#include "src/storage/testing/zxcrypt.h"

namespace fshost {
namespace {

constexpr uint32_t kBlockCount = 1024 * 256;
constexpr uint32_t kBlockSize = 512;
constexpr uint32_t kSliceSize = 32'768;
constexpr size_t kDeviceSize = kBlockCount * kBlockSize;

using MigrationTest = testing::FshostIntegrationTest;

TEST_F(MigrationTest, MigratesZxcryptMinfsToFxfs) {
  if (DataFilesystemFormat() != "fxfs") {
    return;
  }
  PauseWatcher();  // Pause whilst we create a ramdisk.

  // Create a ramdisk with an unformatted minfs partitition.
  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(kDeviceSize, 0, &vmo), ZX_OK);

  // Create a child VMO so that we can keep hold of the original.
  zx::vmo child_vmo;
  ASSERT_EQ(vmo.create_child(ZX_VMO_CHILD_SLICE, 0, kDeviceSize, &child_vmo), ZX_OK);

  constexpr char kFileContents[] = "to be, or not to be?";

  // Now create the ram-disk with a single FVM partition, formatted with zxcrypt, then minfs.
  std::string partition_path_suffix;
  {
    auto ramdisk_or = storage::RamDisk::CreateWithVmo(std::move(child_vmo), kBlockSize);
    ASSERT_EQ(ramdisk_or.status_value(), ZX_OK);
    storage::FvmOptions options{
        .name = kDataPartitionLabel,
        .type = std::array<uint8_t, BLOCK_GUID_LEN>{GUID_DATA_VALUE},
    };
    auto fvm_partition_or = storage::CreateFvmPartition(ramdisk_or->path(), kSliceSize, options);
    ASSERT_EQ(fvm_partition_or.status_value(), ZX_OK);
    auto fvm_topological_path_or = storage::GetTopologicalPath(*fvm_partition_or);
    ASSERT_EQ(fvm_topological_path_or.status_value(), ZX_OK);
    partition_path_suffix = fvm_topological_path_or->substr(ramdisk_or->path().length());

    auto zxcrypt_device_path_or = storage::CreateZxcryptVolume(fvm_partition_or.value());
    ASSERT_EQ(zxcrypt_device_path_or.status_value(), ZX_OK);

    ASSERT_EQ(fs_management::Mkfs(zxcrypt_device_path_or->c_str(),
                                  fs_management::DiskFormat::kDiskFormatMinfs,
                                  fs_management::LaunchStdioSync, fs_management::MkfsOptions{}),
              ZX_OK);

    // Mount the filesystem and add some data.
    auto device_fd = fbl::unique_fd(::open(zxcrypt_device_path_or->c_str(), O_RDONLY));
    ASSERT_TRUE(device_fd) << strerror(errno);
    auto mount_or =
        fs_management::Mount(std::move(device_fd), "/mnt/data", fs_management::kDiskFormatMinfs,
                             fs_management::MountOptions{}, fs_management::LaunchStdioAsync);
    ASSERT_EQ(mount_or.status_value(), ZX_OK);
    auto fd = fbl::unique_fd(::open("/mnt/data/file", O_RDWR | O_CREAT));
    ASSERT_TRUE(fd) << strerror(errno);
    ASSERT_EQ(::write(fd.get(), kFileContents, strlen(kFileContents)),
              static_cast<ssize_t>(strlen(kFileContents)));
  }

  ResumeWatcher();

  // Now reattach the ram-disk.  Fshost should reformat the filesystem as Fxfs and copy the data
  // into it.
  auto ramdisk_or = storage::RamDisk::CreateWithVmo(std::move(vmo), kBlockSize);
  ASSERT_EQ(ramdisk_or.status_value(), ZX_OK);

  // Fxfs should be automatically mounted.
  auto [root_fd, fs_type] = WaitForMount("minfs");
  EXPECT_TRUE(root_fd);
  EXPECT_EQ(fs_type, VFS_TYPE_FXFS);

  // The data should have been copied over.
  auto fd = fbl::unique_fd(::openat(root_fd.get(), "file", O_RDONLY));
  ASSERT_TRUE(fd) << strerror(errno);
  char buf[sizeof(kFileContents)] = {0};
  ASSERT_EQ(::read(fd.get(), buf, sizeof(buf)), static_cast<ssize_t>(strlen(kFileContents)));
  ASSERT_STREQ(buf, kFileContents);

  // We should ensure the device isn't zxcrypt-formatted.
  std::string device_path = ramdisk_or->path() + partition_path_suffix;
  fprintf(stderr, "%s\n", device_path.c_str());
  struct stat st;
  ASSERT_TRUE(::stat(device_path.c_str(), &st) == 0)
      << "Failed to stat " << device_path << ": " << strerror(errno);
  std::string zxcrypt_path = device_path + "/zxcrypt";
  ASSERT_FALSE(::stat(zxcrypt_path.c_str(), &st) == 0) << zxcrypt_path << " shouldn't exist.";

  // No crash reports should have been filed.
  auto client_end = service::Connect<fuchsia_feedback_testing::FakeCrashReporterQuerier>();
  ASSERT_EQ(client_end.status_value(), ZX_OK);
  auto client = fidl::BindSyncClient(std::move(*client_end));
  auto res = client->WatchFile();
  ASSERT_EQ(res.status(), ZX_OK);
  ASSERT_EQ(res->num_filed, 0ul);
}

}  // namespace
}  // namespace fshost
