// 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 <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 <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/storage/fshost/block-device-manager.h"
#include "src/storage/fshost/config.h"
#include "src/storage/fshost/constants.h"
#include "src/storage/fshost/fshost_integration_test.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 FsRecoveryTest = FshostIntegrationTest;

TEST_F(FsRecoveryTest, EmptyPartitionRecoveryTest) {
  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);

  // Now create the ram-disk with a single FVM partition.
  {
    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);
  }

  ResumeWatcher();

  // Now reattach the ram-disk and fshost should format it.
  auto ramdisk_or = storage::RamDisk::CreateWithVmo(std::move(vmo), kBlockSize);
  ASSERT_EQ(ramdisk_or.status_value(), ZX_OK);

  // Minfs should be automatically mounted.
  auto [fd, fs_type] = WaitForMount("minfs");
  EXPECT_TRUE(fd);
  EXPECT_TRUE(fs_type == VFS_TYPE_MINFS || fs_type == VFS_TYPE_FXFS);

  // 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);
}

TEST_F(FsRecoveryTest, CorruptDataRecoveryTest) {
  // TODO(fxbug.dev/99714): This is a kludge!  We should instead read the configured filesystem
  // (data_filesystem_binary_path), and target the specific behaviour we actually want.  We can't do
  // this right now because (a) the test harness can't access the config and (b) the test inherits
  // the global configuration, so we instead have to run the test twice, and check that exactly one
  // of the two cases (minfs or Fxfs) resulted in a crash.
  struct Params {
    fs_management::DiskFormat disk_format;
  };
  const std::array<Params, 2> kParams = {Params{.disk_format = fs_management::kDiskFormatMinfs},
                                         Params{.disk_format = fs_management::kDiskFormatFxfs}};
  int num_crashes = 0;
  for (const auto& params : kParams) {
    std::cerr << "Running test with disk format "
              << fs_management::DiskFormatString(params.disk_format) << std::endl;
    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);

    {
      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 zxcrypt_device_path_or = storage::CreateZxcryptVolume(fvm_partition_or.value());
      ASSERT_EQ(zxcrypt_device_path_or.status_value(), ZX_OK);
      std::string zxcrypt_device_path = std::move(zxcrypt_device_path_or.value());

      // To make it look like there's a filesystem there but it is corrupt, write out the
      // appropriate magic into the otherwise empty block device.
      {
        fbl::unique_fd data_fd(open(zxcrypt_device_path.c_str(), O_RDWR));
        ASSERT_TRUE(data_fd);
        char buf[4096];
        if (params.disk_format == fs_management::kDiskFormatMinfs) {
          ::memcpy(buf, fs_management::kMinfsMagic, sizeof(fs_management::kMinfsMagic));
        } else {
          ::memcpy(buf, fs_management::kFxfsMagic, sizeof(fs_management::kFxfsMagic));
        }
        ASSERT_EQ(pwrite(data_fd.get(), buf, sizeof(buf), 0), static_cast<ssize_t>(sizeof(buf)))
            << "errno: " << strerror(errno);
      }
    }

    ResumeWatcher();

    // Now reattach the ram-disk and fshost should format it.
    auto ramdisk_or = storage::RamDisk::CreateWithVmo(std::move(vmo), kBlockSize);
    ASSERT_EQ(ramdisk_or.status_value(), ZX_OK);

    // Minfs should be automatically mounted.
    auto [fd, fs_type] = WaitForMount("minfs");
    EXPECT_TRUE(fd);
    EXPECT_TRUE(fs_type == VFS_TYPE_MINFS || fs_type == VFS_TYPE_FXFS);

    // If fshost was configured to use (e.g.) Fxfs and the magic was Fxfs' magic, then fshost will
    // treat this as a corruption and file a crash report.  If the magic was something else, fshost
    // treats this as a first boot and just silently reformats.
    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);
    num_crashes += res->num_filed;

    // We need to restart fshost between each test case, because fshost won't bind multiple FVM
    // instances.
    ResetFshost();
  }
  ASSERT_EQ(num_crashes, 1);
}

}  // namespace
}  // namespace fshost
