// 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 "filesystem-mounter.h"

#include <lib/zx/channel.h>
#include <zircon/fidl.h>

#include <blobfs/mount.h>
#include <cobalt-client/cpp/in_memory_logger.h>
#include <zxtest/zxtest.h>

#include "fs-manager.h"
#include "fshost-fs-provider.h"
#include "metrics.h"

namespace devmgr {
namespace {

FsHostMetrics MakeMetrics() {
  return FsHostMetrics(std::make_unique<cobalt_client::Collector>(
      std::make_unique<cobalt_client::InMemoryLogger>()));
}

class FilesystemMounterHarness : public zxtest::Test {
 public:
  void SetUp() override {
    zx::channel dir_request, lifecycle_request;
    ASSERT_OK(FsManager::Create(nullptr, std::move(dir_request), std::move(lifecycle_request),
                                MakeMetrics(), &manager_));
    manager_->WatchExit();
  }

  std::unique_ptr<FsManager> TakeManager() { return std::move(manager_); }

 private:
  std::unique_ptr<FsManager> manager_;
};

using MounterTest = FilesystemMounterHarness;

TEST_F(MounterTest, CreateFilesystemManager) {}

TEST_F(MounterTest, CreateFilesystemMounter) {
  BlockWatcherOptions options = {};
  FilesystemMounter mounter(TakeManager(), options);
}

TEST_F(MounterTest, PkgfsWillNotMountBeforeBlobAndData) {
  BlockWatcherOptions options = {};
  FilesystemMounter mounter(TakeManager(), options);

  ASSERT_FALSE(mounter.BlobMounted());
  ASSERT_FALSE(mounter.DataMounted());
  mounter.TryMountPkgfs();
  EXPECT_FALSE(mounter.PkgfsMounted());
}

enum class FilesystemType {
  kBlobfs,
  kMinfs,
  kFactoryfs,
};

class TestMounter : public FilesystemMounter {
 public:
  template <typename... Args>
  TestMounter(Args&&... args) : FilesystemMounter(std::forward<Args>(args)...) {}

  void ExpectFilesystem(FilesystemType fs) { expected_filesystem_ = fs; }

  zx_status_t LaunchFs(int argc, const char** argv, zx_handle_t* hnd, uint32_t* ids, size_t len,
                       uint32_t fs_flags) final {
    if (argc != 2) {
      return ZX_ERR_INVALID_ARGS;
    }

    switch (expected_filesystem_) {
      case FilesystemType::kBlobfs:
        EXPECT_STR_EQ(argv[0], "/boot/bin/blobfs");
        EXPECT_EQ(fs_flags, FS_SVC | FS_SVC_BLOBFS);
        EXPECT_EQ(len, 3);

        // TODO(fxbug.dev/54521): This check is over-constraining.
        // BlobFS does not *require* this handle to be
        // passed in. However, filesystem-mounter will
        // always pass this handle in. Remove this check
        // once we migrate away from using this handle.
        EXPECT_EQ(ids[2], FS_HANDLE_DIAGNOSTICS_DIR);
        break;
      case FilesystemType::kMinfs:
        EXPECT_STR_EQ(argv[0], "/boot/bin/minfs");
        EXPECT_EQ(fs_flags, FS_SVC);
        EXPECT_EQ(len, 2);
        break;
      case FilesystemType::kFactoryfs:
        EXPECT_STR_EQ(argv[0], "/boot/bin/factoryfs");
        EXPECT_EQ(fs_flags, FS_SVC);
        break;
      default:
        ADD_FAILURE("Unexpected filesystem type");
    }

    EXPECT_STR_EQ(argv[1], "mount");

    EXPECT_EQ(ids[0], FS_HANDLE_ROOT_ID);
    EXPECT_EQ(ids[1], FS_HANDLE_BLOCK_DEVICE_ID);

    zx::channel* server = nullptr;
    switch (expected_filesystem_) {
      case FilesystemType::kBlobfs:
        server = &blobfs_server_;
        break;
      case FilesystemType::kMinfs:
        server = &minfs_server_;
        break;
      case FilesystemType::kFactoryfs:
        server = &factoryfs_server_;
        break;
      default:
        ADD_FAILURE("Unexpected filesystem type");
    }

    server->reset(hnd[0]);
    EXPECT_OK(server->signal_peer(0, ZX_USER_SIGNAL_0));
    EXPECT_OK(zx_handle_close(hnd[1]));
    return ZX_OK;
  }

 private:
  FilesystemType expected_filesystem_ = FilesystemType::kBlobfs;
  zx::channel blobfs_server_;
  zx::channel minfs_server_;
  zx::channel factoryfs_server_;
};

TEST_F(MounterTest, DurableMount) {
  BlockWatcherOptions block_options = {};
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kMinfs);
  ASSERT_OK(mounter.MountDurable(zx::channel(), options));
  ASSERT_TRUE(mounter.DurableMounted());
}

TEST_F(MounterTest, FactoryMount) {
  BlockWatcherOptions block_options = {};
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kFactoryfs);
  ASSERT_OK(mounter.MountFactoryFs(zx::channel(), options));

  ASSERT_TRUE(mounter.FactoryMounted());
}

TEST_F(MounterTest, PkgfsWillNotMountBeforeData) {
  BlockWatcherOptions block_options = {};
  block_options.wait_for_data = true;
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kBlobfs);
  ASSERT_OK(mounter.MountBlob(zx::channel(), options));

  ASSERT_TRUE(mounter.BlobMounted());
  ASSERT_FALSE(mounter.DataMounted());
  mounter.TryMountPkgfs();
  EXPECT_FALSE(mounter.PkgfsMounted());
}

TEST_F(MounterTest, PkgfsWillNotMountBeforeDataUnlessExplicitlyRequested) {
  BlockWatcherOptions block_options = {};
  block_options.wait_for_data = false;
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kBlobfs);
  ASSERT_OK(mounter.MountBlob(zx::channel(), options));

  ASSERT_TRUE(mounter.BlobMounted());
  ASSERT_FALSE(mounter.DataMounted());
  mounter.TryMountPkgfs();
  EXPECT_TRUE(mounter.PkgfsMounted());
}

TEST_F(MounterTest, PkgfsWillNotMountBeforeBlob) {
  BlockWatcherOptions block_options = {};
  block_options.wait_for_data = true;
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kMinfs);
  ASSERT_OK(mounter.MountData(zx::channel(), options));

  ASSERT_FALSE(mounter.BlobMounted());
  ASSERT_TRUE(mounter.DataMounted());
  mounter.TryMountPkgfs();
  EXPECT_FALSE(mounter.PkgfsMounted());
}

TEST_F(MounterTest, PkgfsMountsWithBlobAndData) {
  BlockWatcherOptions block_options = {};
  block_options.wait_for_data = true;
  TestMounter mounter(TakeManager(), block_options);

  mount_options_t options = default_mount_options;
  mounter.ExpectFilesystem(FilesystemType::kBlobfs);
  ASSERT_OK(mounter.MountBlob(zx::channel(), options));
  mounter.ExpectFilesystem(FilesystemType::kMinfs);
  ASSERT_OK(mounter.MountData(zx::channel(), options));

  ASSERT_TRUE(mounter.BlobMounted());
  ASSERT_TRUE(mounter.DataMounted());
  mounter.TryMountPkgfs();
  EXPECT_TRUE(mounter.PkgfsMounted());
}

}  // namespace
}  // namespace devmgr
