// Copyright 2018 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.

#ifndef SRC_VIRTUALIZATION_TESTS_LIB_ENCLOSED_GUEST_H_
#define SRC_VIRTUALIZATION_TESTS_LIB_ENCLOSED_GUEST_H_

#include <fuchsia/virtualization/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/executor.h>
#include <lib/fit/result.h>
#include <lib/sys/component/cpp/testing/realm_builder.h>

#include <memory>

#include <gtest/gtest.h>

#include "lib/async/dispatcher.h"
#include "src/ui/testing/ui_test_manager/ui_test_manager.h"
#include "src/virtualization/lib/vsh/command_runner.h"
#include "src/virtualization/tests/lib/fake_memory_pressure_provider.h"
#include "src/virtualization/tests/lib/fake_netstack.h"
#include "src/virtualization/tests/lib/guest_console.h"
#include "src/virtualization/tests/lib/socket_logger.h"

enum class GuestKernel {
  ZIRCON,
  LINUX,
};

struct GuestLaunchInfo {
  std::string url;
  std::string interface_name;
  fuchsia::virtualization::GuestConfig config;
};
// EnclosedGuest is a base class that defines an guest environment and instance
// encapsulated in an EnclosingEnvironment. A derived class must define the
// |LaunchInfo| to send to the guest environment controller, as well as methods
// for waiting for the guest to be ready and running test utilities. Most tests
// will derive from either ZirconEnclosedGuest or DebianEnclosedGuest below and
// override LaunchInfo only. EnclosedGuest is designed to be used with
// GuestTest.
class EnclosedGuest {
 protected:
  using RunLoopUntilFunc = fit::function<bool(fit::function<bool()>, zx::duration)>;

 public:
  EnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : dispatcher_(dispatcher),
        run_loop_until_(std::move(run_loop_until)),
        fake_memory_pressure_provider_(dispatcher) {}
  virtual ~EnclosedGuest();

  // Start the guest. `Start` is the preferred way to start the guest. If the realm
  // needs to be customized, `Start` can be replaced by a call to `InstallInRealm`
  // followed by a call to `LaunchInRealm`. This should follow a pattern like:
  //
  // ```
  // GuestLaunchInfo guest_launch_info;
  // realm_builder = RealmBuilder::Create();
  // InstallInRealm(realm_builder, guest_launch_info);
  // ...
  // ... // customize realm_builder
  // ...
  // RealmRoot realm_root(realm_builder.Build(dispatcher));
  // LaunchInRealm(realm_root, guest_launch_info, deadline);
  // ```
  //
  // Abort with ZX_ERR_TIMED_OUT if we reach `deadline` before the guest has started.
  zx_status_t Start(zx::time deadline);
  virtual void InstallInRealm(component_testing::Realm& realm, GuestLaunchInfo& guest_launch_info);
  zx_status_t LaunchInRealm(std::unique_ptr<sys::ServiceDirectory> services,
                            GuestLaunchInfo& guest_launch_info, zx::time deadline);

  // Provides guest specific launch info, called by Start.
  virtual zx_status_t BuildLaunchInfo(GuestLaunchInfo* launch_info) = 0;

  // Attempt to gracefully stop the guest.
  //
  // Abort with ZX_ERR_TIMED_OUT if we reach `deadline` first.
  zx_status_t Stop(zx::time deadline);

  // Force stop the guest, and restart it. This can be used to ensure that devices are cleanly
  // brought down and up without needing to destroy the VMM component.
  //
  // Aborts with ZX_ERR_TIMED_OUT if we reach `deadline` first.
  zx_status_t ForceRestart(GuestLaunchInfo& guest_launch_info, zx::time deadline);

  // Execute |command| on the guest serial and wait for the |result|.
  virtual zx_status_t Execute(const std::vector<std::string>& argv,
                              const std::unordered_map<std::string, std::string>& env,
                              zx::time deadline, std::string* result = nullptr,
                              int32_t* return_code = nullptr);

  // Run a test util named |util| with |argv| in the guest and wait for the
  // |result|.
  zx_status_t RunUtil(const std::string& util, const std::vector<std::string>& argv,
                      zx::time deadline, std::string* result = nullptr);

  bool RunLoopUntil(fit::function<bool()> condition, zx::time deadline);

  // Return a shell command for a test utility named |util| with the given
  // |argv| in the guest. The result may be passed directly to |Execute|
  // to actually run the command.
  virtual std::vector<std::string> GetTestUtilCommand(const std::string& util,
                                                      const std::vector<std::string>& argv) = 0;

  virtual GuestKernel GetGuestKernel() = 0;

  fit::result<::fuchsia::virtualization::GuestError> ConnectToBalloon(
      ::fidl::InterfaceRequest<::fuchsia::virtualization::BalloonController> controller);

  fit::result<::fuchsia::virtualization::GuestError> GetHostVsockEndpoint(
      ::fidl::InterfaceRequest<::fuchsia::virtualization::HostVsockEndpoint> endpoint);

  fit::result<::fuchsia::virtualization::GuestError> ConnectToMem(
      ::fidl::InterfaceRequest<::fuchsia::virtualization::MemController> controller);

  template <typename Interface>
  fidl::InterfacePtr<Interface> ConnectToService(
      const std::string& interface_name = Interface::Name_) const {
    return realm_services_->Connect<Interface>(interface_name);
  }

  uint32_t GetGuestCid() const { return guest_cid_; }

  FakeNetstack* GetNetstack() { return &fake_netstack_; }
  FakeMemoryPressureProvider* GetMemoryPressureProvider() {
    return &fake_memory_pressure_provider_;
  }

  std::optional<GuestConsole>& GetConsole() { return console_; }

  // Waits for a view to be created and presented using the GraphicalPresenter protocol.
  //
  // This is appropriate for tests that interact with UI stack in some way and need to interact with
  // the test UI stack.
  struct DisplayInfo {
    uint32_t width;
    uint32_t height;
  };
  DisplayInfo WaitForDisplay();

 protected:
  // Waits until the guest is ready to run test utilities, called by Start.
  virtual zx_status_t WaitForSystemReady(zx::time deadline) = 0;

  // Waits for the guest to perform a graceful shutdown.
  virtual zx_status_t ShutdownAndWait(zx::time deadline) = 0;

  virtual std::string ShellPrompt() = 0;

  // Invoked after the guest |Realm| has been created but before the guest
  // has been launched.
  //
  // Any vsock ports that are listened on here are guaranteed to be ready to
  // accept connections before the guest attempts to connect to them.
  virtual zx_status_t SetupVsockServices(zx::time deadline, GuestLaunchInfo& guest_launch_info) {
    return ZX_OK;
  }

  fuchsia::virtualization::GuestPtr guest_;
  fuchsia::virtualization::HostVsockEndpointPtr vsock_;

 private:
  // Launch the guest into an already prepared realm.
  zx_status_t LaunchInternal(GuestLaunchInfo& guest_launch_info, zx::time deadline);

  std::unique_ptr<sys::ServiceDirectory> StartWithRealmBuilder(zx::time deadline,
                                                               GuestLaunchInfo& guest_launch_info);
  std::unique_ptr<sys::ServiceDirectory> StartWithUITestManager(zx::time deadline,
                                                                GuestLaunchInfo& guest_launch_info);

  async_dispatcher_t* const dispatcher_;
  RunLoopUntilFunc run_loop_until_;
  FakeNetstack fake_netstack_;
  FakeMemoryPressureProvider fake_memory_pressure_provider_;
  fuchsia::virtualization::GuestManagerSyncPtr guest_manager_;
  std::optional<SocketLogger> serial_logger_;
  std::optional<GuestConsole> console_;
  uint32_t guest_cid_;
  // Only one of |ui_test_manager_| and |realm_root_| will be non-null, depending on if graphics
  // APIs are used.
  std::optional<ui_testing::UITestManager> ui_test_manager_;
  std::optional<component_testing::RealmRoot> realm_root_;
  // The exposed services directory for the test realm.
  std::unique_ptr<sys::ServiceDirectory> realm_services_;
  std::optional<zx_status_t> guest_error_;
};

class ZirconEnclosedGuest : public EnclosedGuest {
 public:
  ZirconEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : ZirconEnclosedGuest(dispatcher, std::move(run_loop_until), /* enable_gpu */ false) {}

  std::vector<std::string> GetTestUtilCommand(const std::string& util,
                                              const std::vector<std::string>& argv) override;

  GuestKernel GetGuestKernel() override { return GuestKernel::ZIRCON; }

  zx_status_t BuildLaunchInfo(GuestLaunchInfo* launch_info) override;

 protected:
  ZirconEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until,
                      bool enable_gpu)
      : EnclosedGuest(dispatcher, std::move(run_loop_until)), enable_gpu_(enable_gpu) {}

  zx_status_t WaitForSystemReady(zx::time deadline) override;
  zx_status_t ShutdownAndWait(zx::time deadline) override;
  std::string ShellPrompt() override { return "$ "; }

 private:
  const bool enable_gpu_;
};

class ZirconGpuEnclosedGuest : public ZirconEnclosedGuest {
 public:
  ZirconGpuEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : ZirconEnclosedGuest(dispatcher, std::move(run_loop_until), /* enable_gpu */ true) {}
};

class DebianEnclosedGuest : public EnclosedGuest {
 public:
  DebianEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : DebianEnclosedGuest(dispatcher, std::move(run_loop_until), /* enable_gpu */ false) {}

  std::vector<std::string> GetTestUtilCommand(const std::string& util,
                                              const std::vector<std::string>& argv) override;

  GuestKernel GetGuestKernel() override { return GuestKernel::LINUX; }

  zx_status_t BuildLaunchInfo(GuestLaunchInfo* launch_info) override;

 protected:
  DebianEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until,
                      bool enable_gpu)
      : EnclosedGuest(dispatcher, std::move(run_loop_until)), enable_gpu_(enable_gpu) {}

  zx_status_t WaitForSystemReady(zx::time deadline) override;
  zx_status_t ShutdownAndWait(zx::time deadline) override;
  std::string ShellPrompt() override { return "$ "; }

 private:
  const bool enable_gpu_;
};

class DebianGpuEnclosedGuest : public DebianEnclosedGuest {
 public:
  DebianGpuEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : DebianEnclosedGuest(dispatcher, std::move(run_loop_until), /* enable_gpu */ true) {}
};

class TerminaEnclosedGuest : public EnclosedGuest {
 public:
  TerminaEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : TerminaEnclosedGuest(dispatcher, std::move(run_loop_until),
                             fuchsia::virtualization::ContainerStatus::STARTING_VM) {}

  GuestKernel GetGuestKernel() override { return GuestKernel::LINUX; }

  std::vector<std::string> GetTestUtilCommand(const std::string& util,
                                              const std::vector<std::string>& argv) override;
  zx_status_t Execute(const std::vector<std::string>& command,
                      const std::unordered_map<std::string, std::string>& env, zx::time deadline,
                      std::string* result, int32_t* return_code) override;

  zx_status_t BuildLaunchInfo(GuestLaunchInfo* launch_info) override;
  void InstallInRealm(component_testing::Realm& realm, GuestLaunchInfo& guest_launch_info) override;

 protected:
  TerminaEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until,
                       fuchsia::virtualization::ContainerStatus target_status)
      : EnclosedGuest(dispatcher, std::move(run_loop_until)),
        target_status_(target_status),
        executor_(dispatcher) {}

  zx_status_t WaitForSystemReady(zx::time deadline) override;
  zx_status_t ShutdownAndWait(zx::time deadline) override;
  std::string ShellPrompt() override { return "$ "; }

 private:
  const fuchsia::virtualization::ContainerStatus target_status_;
  std::unique_ptr<vsh::BlockingCommandRunner> command_runner_;
  async::Executor executor_;
  ::fuchsia::virtualization::LinuxManagerPtr linux_manager_;
};

class TerminaContainerEnclosedGuest : public TerminaEnclosedGuest {
 public:
  TerminaContainerEnclosedGuest(async_dispatcher_t* dispatcher, RunLoopUntilFunc run_loop_until)
      : TerminaEnclosedGuest(dispatcher, std::move(run_loop_until),
                             fuchsia::virtualization::ContainerStatus::READY) {}

  zx_status_t BuildLaunchInfo(GuestLaunchInfo* launch_info) override;
  void InstallInRealm(component_testing::Realm& realm, GuestLaunchInfo& guest_launch_info) override;
  zx_status_t WaitForSystemReady(zx::time deadline) override;
  zx_status_t Execute(const std::vector<std::string>& argv,
                      const std::unordered_map<std::string, std::string>& env, zx::time deadline,
                      std::string* result, int32_t* return_code) override;
};

using AllGuestTypes = ::testing::Types<ZirconEnclosedGuest, DebianEnclosedGuest>;

class GuestTestNameGenerator {
 public:
  template <typename T>
  static std::string GetName(int idx) {
    // Use is_base_of because some tests will use sub-classes. By default gtest will just use
    // idx to string, so we just suffix the actual enclosed guest type.
    if (std::is_base_of<ZirconEnclosedGuest, T>())
      return std::to_string(idx) + "_ZirconGuest";
    if (std::is_base_of<DebianEnclosedGuest, T>())
      return std::to_string(idx) + "_DebianGuest";
    if (std::is_base_of<TerminaContainerEnclosedGuest, T>())
      return std::to_string(idx) + "_TerminaContainerGuest";
    if (std::is_base_of<TerminaEnclosedGuest, T>())
      return std::to_string(idx) + "_TerminaGuest";
  }
};

#endif  // SRC_VIRTUALIZATION_TESTS_LIB_ENCLOSED_GUEST_H_
