// 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 "src/modular/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 <thread>

#include <gtest/gtest.h>
#include <src/lib/files/file.h>
#include <src/lib/files/path.h>
#include <src/modular/lib/modular_config/modular_config.h>
#include <src/modular/lib/modular_config/modular_config_constants.h>
#include <src/modular/lib/pseudo_dir/pseudo_dir_server.h>

#include "src/lib/fxl/strings/split_string.h"
#include "src/lib/fxl/strings/substitute.h"

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_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(), [this] { did_exit_ = true; }) {
    harness_impl_.Bind(harness_.NewRequest());
  }

  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(std::string(dir_split[1]), MakeBasemgrConfigDir(std::move(spec)));
    namespace_dir->AddEntry(std::string(dir_split[0]), 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_devicesettingsmgr_url = GenerateFakeUrl();

  spec.mutable_env_services()->mutable_services_from_components()->push_back(
      fuchsia::modular::testing::ComponentService{
          // Override the default injected DeviceSettingsManager.
          .name = fuchsia::devicesettings::DeviceSettingsManager::Name_,
          .url = generated_devicesettingsmgr_url});

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

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

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

  fuchsia::devicesettings::DeviceSettingsManagerPtr devicesettingsmgr;
  test_harness()->ConnectToEnvironmentService(fuchsia::devicesettings::DeviceSettingsManager::Name_,
                                              devicesettingsmgr.NewRequest().TakeChannel());

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

// 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, ComponentProvidedService) {
  fuchsia::modular::testing::TestHarnessSpec spec;

  auto generated_componentctx_url = GenerateFakeUrl();

  spec.mutable_env_services()->mutable_services_from_components()->push_back(
      fuchsia::modular::testing::ComponentService{// 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, 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::ModularService svc;
  svc.set_puppet_master(puppet_master.NewRequest());
  test_harness()->ConnectToModularService(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) {});

  RunLoopUntil([&] { return story_shell_intercepted; });
  RunLoopUntil([&] { return fake_module_intercepted; });
};

// Tests that services in |TestHarnessSpec.env_services.service_dir| are
// accessible in the test harness environment.
TEST_F(TestHarnessImplTest, EnvironmentServiceDirectory) {
  constexpr char kTestServiceName[] = "my.test.service";

  bool svc_requested = false;
  auto svc_dir = std::make_unique<vfs::PseudoDir>();
  svc_dir->AddEntry(kTestServiceName,
                    std::make_unique<vfs::Service>(
                        [&svc_requested](zx::channel request, async_dispatcher_t* dispatcher) {
                          svc_requested = true;
                        }));

  modular::PseudoDirServer svc_dir_server(std::move(svc_dir));

  fuchsia::modular::testing::TestHarnessSpec spec;
  spec.mutable_env_services()->set_service_dir(svc_dir_server.Serve().Unbind().TakeChannel());
  test_harness()->Run(std::move(spec));

  fuchsia::io::NodePtr node;
  test_harness()->ConnectToEnvironmentService(kTestServiceName, node.NewRequest().TakeChannel());
  RunLoopUntil([&] { return svc_requested; });
}

// Tests that that the test harness correctly parses modular configs from a
// string.
TEST_F(TestHarnessImplTest, ParseConfigFromString) {
  auto config = R"({
  "basemgr": {
    "base_shell": {
      "url": "fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
      "keep_alive_after_login": true
    },
    "session_shells": [
      {
        "url": "fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
        "display_usage": "near"
      }
    ]
  },
  "sessionmgr": {
    "startup_agents": [
      "fuchsia-pkg://fuchsia.com/startup_agent#meta/startup_agent.cmx"
    ]
  }
  })";

  fuchsia::modular::session::BasemgrConfig basemgr_config;
  fuchsia::modular::session::SessionmgrConfig sessionmgr_config;
  bool done = false;
  test_harness()->ParseConfig(
      config, [&](fuchsia::modular::session::BasemgrConfig parsed_basemgr_config,
                  fuchsia::modular::session::SessionmgrConfig parsed_sessionmgr_config) {
        basemgr_config = std::move(parsed_basemgr_config);
        sessionmgr_config = std::move(parsed_sessionmgr_config);
        done = true;
      });

  RunLoopUntil([&] { return done; });
  EXPECT_EQ("fuchsia-pkg://fuchsia.com/dev_base_shell#meta/dev_base_shell.cmx",
            basemgr_config.base_shell().app_config().url());
  ASSERT_EQ(1u, basemgr_config.session_shell_map().size());
  EXPECT_EQ("fuchsia-pkg://fuchsia.com/dev_session_shell#meta/dev_session_shell.cmx",
            basemgr_config.session_shell_map().at(0).config().app_config().url());
}

}  // namespace
}  // namespace modular_testing
