// 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 "lib/modular_test_harness/cpp/test_harness_impl.h"

#include <fuchsia/modular/session/cpp/fidl.h>
#include <fuchsia/modular/testing/cpp/fidl.h>
#include <lib/sys/cpp/testing/test_with_environment.h>
#include <lib/vfs/cpp/pseudo_dir.h>
#include <peridot/lib/modular_config/modular_config.h>
#include <peridot/lib/modular_config/modular_config_constants.h>
#include <peridot/lib/util/pseudo_dir_server.h>
#include <src/lib/files/file.h>
#include <src/lib/files/path.h>
#include <src/lib/fxl/strings/split_string.h>
#include <src/lib/fxl/strings/substitute.h>

#include <thread>

#include "gtest/gtest.h"

constexpr char kFakeBaseShellUrl[] =
    "fuchsia-pkg://example.com/FAKE_BASE_SHELL_PKG/fake_base_shell.cmx";
constexpr char kFakeSessionShellUrl[] =
    "fuchsia-pkg://example.com/FAKE_SESSION_SHELL_PKG/fake_session_shell.cmx";
constexpr char kFakeStoryShellUrl[] =
    "fuchsia-pkg://example.com/FAKE_STORY_SHELL_PKG/fake_story_shell.cmx";
constexpr char kFakeModuleUrl[] =
    "fuchsia-pkg://example.com/FAKE_MODULE_PKG/fake_module.cmx";

namespace modular {
namespace testing {
namespace {
std::string GenerateFakeUrl() {
  uint32_t random_number = 0;
  zx_cprng_draw(&random_number, sizeof random_number);
  constexpr char kFakeUrlSubstitutePattern[] =
      "fuchsia-pkg://example.com/GENERATED_URL_$0#meta/GENERATED_URL_$0.cmx";
  return fxl::Substitute(kFakeUrlSubstitutePattern,
                         std::to_string(random_number));
}
};  // namespace

class TestHarnessImplTest : public sys::testing::TestWithEnvironment {
 public:
  TestHarnessImplTest()
      : harness_impl_(real_env(), harness_.NewRequest(),
                      [this] { did_exit_ = true; }) {}

  fuchsia::modular::testing::TestHarnessPtr& test_harness() {
    return harness_;
  };

  bool did_exit() { return did_exit_; }

  std::unique_ptr<vfs::PseudoDir> MakeBasemgrConfigDir(
      fuchsia::modular::testing::TestHarnessSpec spec) {
    return TestHarnessImpl::MakeBasemgrConfigDir(std::move(spec));
  }

 private:
  bool did_exit_ = false;
  fuchsia::modular::testing::TestHarnessPtr harness_;
  ::modular::testing::TestHarnessImpl harness_impl_;
};

namespace {

// Closing the TestHarness connection will cause TestHarnessImpl to notify that
// it's not usable.
TEST_F(TestHarnessImplTest, ExitCallback) {
  test_harness().Unbind();
  RunLoopUntil([&] { return did_exit(); });
}

// Check that the config that TestHarnessImpl generates is readable by
// ModuleConfigReader.
TEST_F(TestHarnessImplTest, MakeBasemgrConfigDir) {
  constexpr char kSessionShellForTest[] =
      "fuchsia-pkg://example.com/TestHarnessImplTest#meta/"
      "TestHarnessImplTest.cmx";

  fuchsia::modular::testing::TestHarnessSpec spec;
  fuchsia::modular::session::SessionShellMapEntry session_shell_entry;
  session_shell_entry.mutable_config()->mutable_app_config()->set_url(
      kSessionShellForTest);

  spec.mutable_basemgr_config()->mutable_session_shell_map()->push_back(
      std::move(session_shell_entry));

  // Construct "/config_override/data" dirs, and add MakeBasemgrConfigDir() to
  // "data" dir.
  auto namespace_dir = std::make_unique<vfs::PseudoDir>();
  {
    auto dir_split =
        fxl::SplitString(modular_config::kOverriddenConfigDir, "/",
                         fxl::kTrimWhitespace, fxl::kSplitWantNonEmpty);
    ASSERT_EQ(2u, dir_split.size());

    auto second_dir = std::make_unique<vfs::PseudoDir>();
    second_dir->AddEntry(dir_split[1].ToString(),
                         MakeBasemgrConfigDir(std::move(spec)));
    namespace_dir->AddEntry(dir_split[0].ToString(), std::move(second_dir));
  }

  modular::PseudoDirServer server(std::move(namespace_dir));
  modular::ModularConfigReader config_reader(server.OpenAt("."));
  EXPECT_EQ(kSessionShellForTest, config_reader.GetBasemgrConfig()
                                      .session_shell_map()
                                      .at(0)
                                      .config()
                                      .app_config()
                                      .url());
}

// Test that additional injected services are made available, spin up the
// associated component when requested. This test exercises overriding a default
// injected service.
TEST_F(TestHarnessImplTest, DefaultInjectedServices) {
  fuchsia::modular::testing::TestHarnessSpec spec;

  auto generated_accountmgr_url = GenerateFakeUrl();

  spec.mutable_env_services_to_inject()->push_back(
      fuchsia::modular::testing::InjectedService{
          // Override the default injected AccountManager.
          .name = fuchsia::auth::account::AccountManager::Name_,
          .url = generated_accountmgr_url});

  // Intercept the component URL which supplies AccountManager.
  {
    fuchsia::modular::testing::InterceptSpec intercept_spec;
    intercept_spec.set_component_url(generated_accountmgr_url);
    spec.mutable_components_to_intercept()->push_back(
        std::move(intercept_spec));
  }

  bool intercepted_accountmgr = false;
  test_harness().events().OnNewComponent =
      [&](fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        if (startup_info.launch_info.url == generated_accountmgr_url) {
          intercepted_accountmgr = true;
        } else {
          ASSERT_FALSE("Started for no reason.");
        }
      };

  test_harness()->Run(std::move(spec));

  fuchsia::auth::account::AccountManagerPtr accountmgr;
  test_harness()->ConnectToEnvironmentService(
      fuchsia::auth::account::AccountManager::Name_,
      accountmgr.NewRequest().TakeChannel());

  RunLoopUntil([&] { return intercepted_accountmgr; });
}

// Test that additional injected services are made available, spin up the
// associated component when requested. This test exercises injecting a custom
// service.
TEST_F(TestHarnessImplTest, CustomInjectedServices) {
  fuchsia::modular::testing::TestHarnessSpec spec;

  auto generated_componentctx_url = GenerateFakeUrl();

  spec.mutable_env_services_to_inject()->push_back(
      fuchsia::modular::testing::InjectedService{
          // Provide a custom injected service.
          .name = fuchsia::modular::ComponentContext::Name_,
          .url = generated_componentctx_url});

  // Intercept the component URL which supplies ComponentContext.
  {
    fuchsia::modular::testing::InterceptSpec intercept_spec;
    intercept_spec.set_component_url(generated_componentctx_url);
    spec.mutable_components_to_intercept()->push_back(
        std::move(intercept_spec));
  }

  bool intercepted_componentctx = false;
  test_harness().events().OnNewComponent =
      [&](fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        if (startup_info.launch_info.url == generated_componentctx_url) {
          intercepted_componentctx = true;
        } else {
          ASSERT_FALSE("Started for no reason.");
        }
      };

  test_harness()->Run(std::move(spec));

  fuchsia::modular::ComponentContextPtr componentctx;
  test_harness()->ConnectToEnvironmentService(
      fuchsia::modular::ComponentContext::Name_,
      componentctx.NewRequest().TakeChannel());

  RunLoopUntil([&] { return intercepted_componentctx; });
}

TEST_F(TestHarnessImplTest, InterceptBaseShell) {
  // Setup base shell interception.
  fuchsia::modular::testing::InterceptSpec shell_intercept_spec;
  shell_intercept_spec.set_component_url(kFakeBaseShellUrl);

  fuchsia::modular::testing::TestHarnessSpec spec;
  spec.mutable_basemgr_config()
      ->mutable_base_shell()
      ->mutable_app_config()
      ->set_url(kFakeBaseShellUrl);
  spec.mutable_components_to_intercept()->push_back(
      std::move(shell_intercept_spec));

  // Listen for base shell interception.
  bool intercepted = false;

  test_harness().events().OnNewComponent =
      [&](fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        ASSERT_EQ(kFakeBaseShellUrl, startup_info.launch_info.url);
        intercepted = true;
      };

  test_harness()->Run(std::move(spec));

  RunLoopUntil([&] { return intercepted; });
};

TEST_F(TestHarnessImplTest, InterceptSessionShell) {
  fuchsia::modular::testing::TestHarnessSpec spec;

  // 1. Setup session shell interception.
  fuchsia::modular::testing::InterceptSpec shell_intercept_spec;
  shell_intercept_spec.set_component_url(kFakeSessionShellUrl);
  {
    fuchsia::modular::session::SessionShellMapEntry entry;
    entry.mutable_config()->mutable_app_config()->set_url(kFakeSessionShellUrl);

    spec.mutable_basemgr_config()->mutable_session_shell_map()->push_back(
        std::move(entry));
  }
  spec.mutable_components_to_intercept()->push_back(
      std::move(shell_intercept_spec));

  // 2. Listen for session shell interception.
  bool intercepted = false;
  test_harness().events().OnNewComponent =
      [&intercepted](
          fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        if (startup_info.launch_info.url == kFakeSessionShellUrl)
          intercepted = true;
      };

  test_harness()->Run(std::move(spec));

  RunLoopUntil([&] { return intercepted; });
};

TEST_F(TestHarnessImplTest, InterceptStoryShellAndModule) {
  // Setup story shell interception.
  fuchsia::modular::testing::InterceptSpec shell_intercept_spec;
  shell_intercept_spec.set_component_url(kFakeStoryShellUrl);

  fuchsia::modular::testing::TestHarnessSpec spec;
  spec.mutable_basemgr_config()
      ->mutable_story_shell()
      ->mutable_app_config()
      ->set_url(shell_intercept_spec.component_url());
  spec.mutable_components_to_intercept()->push_back(
      std::move(shell_intercept_spec));

  // Setup kFakeModuleUrl interception.
  {
    fuchsia::modular::testing::InterceptSpec intercept_spec;
    intercept_spec.set_component_url(kFakeModuleUrl);
    spec.mutable_components_to_intercept()->push_back(
        std::move(intercept_spec));
  }

  // Listen for story shell interception.
  bool story_shell_intercepted = false;
  // Listen for module interception.
  bool fake_module_intercepted = false;

  test_harness().events().OnNewComponent =
      [&](fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        if (startup_info.launch_info.url == kFakeModuleUrl) {
          fake_module_intercepted = true;
        } else if (startup_info.launch_info.url == kFakeStoryShellUrl) {
          story_shell_intercepted = true;
        }
      };
  test_harness()->Run(std::move(spec));

  // Create a new story -- this should auto-start the story (because of
  // test_session_shell's behaviour), and launch a new story shell.
  fuchsia::modular::PuppetMasterPtr puppet_master;
  fuchsia::modular::StoryPuppetMasterPtr story_master;

  fuchsia::modular::testing::TestHarnessService svc;
  svc.set_puppet_master(puppet_master.NewRequest());
  test_harness()->GetService(std::move(svc));

  puppet_master->ControlStory("my_story", story_master.NewRequest());

  using fuchsia::modular::AddMod;
  using fuchsia::modular::StoryCommand;

  std::vector<StoryCommand> cmds;
  StoryCommand cmd;
  AddMod add_mod;
  add_mod.mod_name = {"mod_name"};
  add_mod.intent.handler = kFakeModuleUrl;
  add_mod.surface_relation = fuchsia::modular::SurfaceRelation{};
  cmd.set_add_mod(std::move(add_mod));
  cmds.push_back(std::move(cmd));

  story_master->Enqueue(std::move(cmds));
  story_master->Execute([](fuchsia::modular::ExecuteResult result) {});

  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&] { return story_shell_intercepted; },
                                        zx::sec(10)));
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&] { return fake_module_intercepted; },
                                        zx::sec(10)));
};

}  // namespace
}  // namespace testing
}  // namespace modular
