// 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 LIB_SYS_CPP_TESTING_TEST_WITH_ENVIRONMENT_H_
#define LIB_SYS_CPP_TESTING_TEST_WITH_ENVIRONMENT_H_

#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async-loop/testing/cpp/real_loop.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/cpp/testing/enclosing_environment.h>
#include <lib/sys/cpp/testing/launcher_impl.h>

namespace sys {
namespace testing {

// Combines the return code and termination reason from a Component termination.
struct TerminationResult {
  int64_t return_code;
  fuchsia::sys::TerminationReason reason;
};

// Test fixture for tests to run Components inside a new isolated Environment,
// wrapped in a enclosing Environment. Typically, the implementing test class
// derives from both `TestWithEnvironment` and a test framework fixture, such
// as gtest fixture `testing::Test`.
//
// The new isolated Environment, provided to the Component under test, is not
// visible to any real Environments, such as the Environment that the test
// program was launched in.
//
// That isloated environment needs to be created using
// |CreateNewEnclosingEnvironment*| APIs.
//
// The isolated Environment is enclosed in a enclosing Environment, allowing the
// test to provide Loader, Services, and other Directories that are visible to
// Components under test, and only to those Components.
//
// This fixture also allows you to create components in the real environment in
// which this test was launched. Those components should only be used to
// validate real system state.
//
// To use this fixture you need to whitelist "fuchsia.sys.Environment" and
// "fuchsia.sys.Loader" in your component manifest file in "sandbox.services".
// It is necessary because this fixture needs to access
// "fuchsia.sys.Environment" and if you create a |EnclosingEnvironment| then it
// will need access to parent's "fuchsia.sys.Loader" to serve it own Loader
// service.
//
// If you are going to create a new EnclosingEnvironment then you also need to
// run your own loop to serve services provided by that environment. So use of
// SyncPtrs is not advisable unless you can run a loop safely in a new thread
// which stops running before you kill your EnclosingEnvironment.
class TestWithEnvironment : public loop_fixture::RealLoop {
 protected:
  TestWithEnvironment();

  fuchsia::sys::LauncherPtr launcher_ptr() {
    fuchsia::sys::LauncherPtr launcher;
    real_launcher_.AddBinding(launcher.NewRequest());
    return launcher;
  }

  const std::shared_ptr<sys::ServiceDirectory>& real_services() { return real_services_; }

  const fuchsia::sys::EnvironmentPtr& real_env() { return real_env_; }

  // Creates a new enclosing environment inside current real environment with
  // the given services.
  //
  // This environment and components created in it will not have access to any
  // of services(except Loader) and resources from the real environment unless
  // explicitly allowed by calling AllowPublicService.
  //
  // After all services are added/passed through to the environment, you must
  // call Launch() to actually start it.
  std::unique_ptr<EnclosingEnvironment> CreateNewEnclosingEnvironment(
      const std::string& label, std::unique_ptr<EnvironmentServices> services,
      const fuchsia::sys::EnvironmentOptions& options = {}) const {
    return EnclosingEnvironment::Create(label, real_env_, std::move(services), options);
  }

  // Returns an EnvironmentServices object that the caller can use to pass
  // services to a new EnclosingEnvironment.
  //
  // The returned object has the parent's loader, but no other services by
  // default.
  std::unique_ptr<EnvironmentServices> CreateServices() {
    return EnvironmentServices::Create(real_env_);
  }

  std::unique_ptr<EnvironmentServices> CreateServicesWithParentOverrides(
      EnvironmentServices::ParentOverrides parent_overrides) {
    return EnvironmentServices::CreateWithParentOverrides(real_env_, std::move(parent_overrides));
  }

  // Creates component in current real environment. This component will have
  // access to the services, directories and other resources from the
  // environment in which your test was launched.
  //
  // This should be mostly used for observing the state of system and for
  // nothing else. For eg. Try launching "glob" component and validate how it
  // behaves in various environments.
  void CreateComponentInCurrentEnvironment(
      fuchsia::sys::LaunchInfo launch_info,
      fidl::InterfaceRequest<fuchsia::sys::ComponentController> request);

  // Waits for the environment to start.
  //
  // You should either use this function to wait or run your own loop if you
  // want CreateComponent* to succed on |enclosing_environment|.
  void WaitForEnclosingEnvToStart(const EnclosingEnvironment* enclosing_environment) {
    RunLoopUntil([enclosing_environment] { return enclosing_environment->is_running(); });
  }

  // Kills and waits for environment to terminate.
  //
  // You should either use this function to wait or run your own loop if you
  // want to wait for your environment to be killed.
  void KillEnclosingEnvironment(EnclosingEnvironment* enclosing_environment) {
    bool killed = false;
    enclosing_environment->Kill([&] { killed = true; });
    RunLoopUntil([&] { return killed; });
  }

  // Run a loop until the given component is terminated or |timeout| elapses.
  bool RunComponentUntilTerminated(fuchsia::sys::ComponentControllerPtr component_controller,
                                   TerminationResult* termination_result = nullptr);

 private:
  std::shared_ptr<sys::ServiceDirectory> real_services_;
  fuchsia::sys::EnvironmentPtr real_env_;
  LauncherImpl real_launcher_;
};

}  // namespace testing
}  // namespace sys

#endif  // LIB_SYS_CPP_TESTING_TEST_WITH_ENVIRONMENT_H_
