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

#include <fuchsia/inspect/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/cpp/executor.h>
#include <lib/async/default.h>
#include <lib/fdio/directory.h>
#include <lib/inspect/service/cpp/reader.h>
#include <lib/sys/cpp/file_descriptor.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/sys/cpp/testing/test_with_environment.h>

#include <fidl/examples/echo/cpp/fidl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "garnet/bin/sysmgr/config.h"
#include "lib/inspect/cpp/hierarchy.h"
#include "lib/inspect/cpp/vmo/types.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/glob.h"
#include "src/lib/fxl/strings/concatenate.h"
#include "src/lib/fxl/strings/join_strings.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace component {
namespace {

// This test fixture will provide a way to run components in provided launchers
// and check for errors.
class HubTest : public sys::testing::TestWithEnvironment {
 protected:
  // This would launch component and check that it returns correct
  // |expected_return_code|.
  void RunComponent(const fuchsia::sys::LauncherPtr& launcher, const std::string& component_url,
                    const std::vector<std::string>& args, int64_t expected_return_code) {
    std::FILE* outf = std::tmpfile();
    int out_fd = fileno(outf);
    fuchsia::sys::LaunchInfo launch_info;
    launch_info.url = component_url;
    launch_info.arguments = args;

    launch_info.out = sys::CloneFileDescriptor(out_fd);

    fuchsia::sys::ComponentControllerPtr controller;
    launcher->CreateComponent(std::move(launch_info), controller.NewRequest());

    int64_t return_code = INT64_MIN;
    controller.events().OnTerminated = [&return_code](int64_t code,
                                                      fuchsia::sys::TerminationReason reason) {
      return_code = code;
    };
    RunLoopUntil([&return_code] { return return_code != INT64_MIN; });
    std::string output;
    ASSERT_TRUE(files::ReadFileDescriptorToString(out_fd, &output));
    EXPECT_EQ(expected_return_code, return_code)
        << "failed for: " << fxl::JoinStrings(args, ", ") << "\noutput: " << output;
  }
};

using ProbeHub = HubTest;

TEST_F(ProbeHub, Component) {
  std::string echo_url = "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/echo_server.cmx";

  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url = echo_url;
  auto echo_svc = sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);

  fuchsia::sys::ComponentControllerPtr controller;
  launcher_ptr()->CreateComponent(std::move(launch_info), controller.NewRequest());

  bool directory_ready = false;
  controller.events().OnDirectoryReady = [&] { directory_ready = true; };

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

  constexpr char kGlob[] = "/hub/c/echo_server.cmx/*/out/debug";
  files::Glob glob(kGlob);
  EXPECT_GE(glob.size(), 1u) << kGlob << " expected to match at least once.";

  std::string kGlob_svc =
      std::string("/hub/c/echo_server.cmx/*/out/svc/") + fidl::examples::echo::Echo::Name_;
  files::Glob glob_svc(kGlob_svc);
  EXPECT_GE(glob_svc.size(), 1u) << kGlob_svc << " expected to match at least once.";
}

TEST_F(ProbeHub, Realm) {
  constexpr char kGlob[] = "/hub/c/";
  files::Glob glob(kGlob);
  EXPECT_EQ(glob.size(), 1u) << kGlob << " expected to match once.";
}

TEST_F(ProbeHub, RealmSvc) {
  constexpr char kGlob[] = "/hub/svc/fuchsia.sys.Environment";
  files::Glob glob(kGlob);
  EXPECT_EQ(glob.size(), 1u);
}

TEST_F(HubTest, Services) {
  // Services for sys.
  {
    constexpr char kGlob[] = "/hub/svc";
    files::Glob glob(kGlob);
    EXPECT_EQ(glob.size(), 1u) << kGlob << " expected to match once.";
    const std::string path = *glob.begin();

    // Expect at least these built-in services
    std::vector<std::string> expected_files = {
      ".",
      "fuchsia.boot.FactoryItems",
      "fuchsia.boot.ReadOnlyLog",
      "fuchsia.boot.RootResource",
      "fuchsia.boot.WriteOnlyLog",
      "fuchsia.device.NameProvider",
      "fuchsia.device.manager.Administrator",
      "fuchsia.device.manager.DebugDumper",
      "fuchsia.hardware.pty.Device",
      "fuchsia.kernel.Counter",
      "fuchsia.kernel.DebugBroker",
      "fuchsia.kernel.DebugResource",
      "fuchsia.kernel.HypervisorResource",
      "fuchsia.kernel.InfoResource",
#if __x86_64__
      "fuchsia.kernel.IoportResource",
#elif __aarch64__
      "fuchsia.kernel.SmcResource",
#endif
      "fuchsia.kernel.IrqResource",
      "fuchsia.kernel.MmioResource",
      "fuchsia.kernel.RootJob",
      "fuchsia.kernel.RootJobForInspect",
      "fuchsia.kernel.Stats",
      "fuchsia.kernel.VmexResource",
      "fuchsia.tracing.kernel.Controller",
      "fuchsia.tracing.kernel.Reader",
      "fuchsia.paver.Paver",
      "fuchsia.process.Launcher",
      "fuchsia.process.Resolver",
      "fuchsia.scheduler.ProfileProvider",
      "fuchsia.sys.Environment",
      "fuchsia.sys.Launcher",
      "fuchsia.sys.Loader",
      "fuchsia.sys.test.CacheControl",
      "fuchsia.sysinfo.SysInfo",
      "fuchsia.virtualconsole.SessionManager"
    };
    sysmgr::Config config;
    const auto service_map = config.TakeServices();
    for (const auto& e : service_map) {
      expected_files.push_back(e.first);
    }

    // readdir should list all services.
    std::vector<std::string> files;
    ASSERT_TRUE(files::ReadDirContents(path, &files));
    EXPECT_THAT(expected_files, ::testing::IsSubsetOf(files));
  }
}

TEST_F(HubTest, ScopePolicy) {
  constexpr char kGlobUrl[] = "fuchsia-pkg://fuchsia.com/glob#meta/glob.cmx";
  // create nested environment
  // test that we can see nested env
  auto nested_env = CreateNewEnclosingEnvironment("hubscopepolicytest", CreateServices());
  WaitForEnclosingEnvToStart(nested_env.get());
  RunComponent(launcher_ptr(), kGlobUrl, {"/hub/r/hubscopepolicytest/"}, 0);

  // test that we cannot see nested env using its own launcher
  RunComponent(nested_env->launcher_ptr(), kGlobUrl, {"/hub/r/hubscopepolicytest"}, 1);

  // test that we can see check_hub_path
  RunComponent(nested_env->launcher_ptr(), kGlobUrl, {"/hub/c/glob.cmx"}, 0);
}

TEST_F(HubTest, SystemDiagnostics) {
  std::string glob_url = "fuchsia-pkg://fuchsia.com/glob#meta/glob.cmx";

  auto nested_env = CreateNewEnclosingEnvironment("hubscopepolicytest", CreateServices());
  WaitForEnclosingEnvToStart(nested_env.get());
  RunComponent(launcher_ptr(), glob_url, {"/hub/r/hubscopepolicytest/"}, 0);

  // test that we can see system objects
  RunComponent(nested_env->launcher_ptr(), glob_url, {"/hub/c/glob.cmx/*/system_diagnostics"}, 0);
}

TEST_F(HubTest, SystemDiagnosticsData) {
  std::string url =
      "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/"
      "appmgr_integration_tests_inspect_test_app.cmx";

  auto env_name = fxl::StringPrintf("test-%lu", time(NULL));

  auto nested_env = CreateNewEnclosingEnvironment(env_name, CreateServices());
  WaitForEnclosingEnvToStart(nested_env.get());

  fuchsia::sys::ComponentControllerPtr controller = nested_env->CreateComponentFromUrl(url);
  bool ready = false;
  controller.events().OnDirectoryReady = [&] { ready = true; };
  RunLoopUntil([&] { return ready; });

  std::vector<std::string> paths;
  for (auto val : files::Glob(
           fxl::StringPrintf("/hub/r/%s/*/c/appmgr_integration_tests_inspect_test_app.cmx/*/"
                             "system_diagnostics/*",
                             env_name.c_str()))) {
    paths.emplace_back(std::move(val));
  }

  ASSERT_EQ(1U, paths.size());

  fuchsia::inspect::TreePtr tree;
  fdio_service_connect(paths[0].c_str(), tree.NewRequest().TakeChannel().release());
  auto read = inspect::ReadFromTree(std::move(tree));
  async::Executor executor_(dispatcher());

  fit::result<inspect::Hierarchy> result;
  executor_.schedule_task(
      read.then([&](fit::result<inspect::Hierarchy>& res) { result = std::move(res); }));

  RunLoopUntil([&] { return !!result; });

  ASSERT_TRUE(result.is_ok());

  auto* threads = result.value().GetByPath({"threads"});
  ASSERT_NE(nullptr, threads);
  EXPECT_NE(0u, threads->children().size());
  auto* stack = threads->children()[0].GetByPath({"stack"});
  ASSERT_NE(nullptr, stack);
  auto* dump = stack->node().get_property<inspect::StringPropertyValue>("dump");
  ASSERT_NE(nullptr, dump);

  auto* handle_count = result.value().GetByPath({"handle_count"});
  ASSERT_NE(nullptr, handle_count);
  auto* vmo = handle_count->node().get_property<inspect::UintPropertyValue>("vmo");
  ASSERT_NE(nullptr, vmo);
  EXPECT_NE(0u, vmo->value());

  auto* memory = result.value().GetByPath({"memory"});
  ASSERT_NE(nullptr, memory);
  std::vector<std::string> names;
  for (const auto& prop : memory->node().properties()) {
    names.emplace_back(prop.name());
  }

  EXPECT_THAT(names, testing::UnorderedElementsAre("mapped_bytes", "shared_bytes", "private_bytes",
                                                   "scaled_shared_bytes"));
}

TEST_F(HubTest, SystemDiagnosticsInUseWhileFreed) {
  std::string url =
      "fuchsia-pkg://fuchsia.com/appmgr_integration_tests#meta/"
      "appmgr_integration_tests_inspect_test_app.cmx";

  auto env_name = fxl::StringPrintf("test-%lu", time(NULL));

  auto nested_env = CreateNewEnclosingEnvironment(env_name, CreateServices());
  WaitForEnclosingEnvToStart(nested_env.get());

  fuchsia::sys::ComponentControllerPtr controller = nested_env->CreateComponentFromUrl(url);
  bool ready = false;
  controller.events().OnDirectoryReady = [&] { ready = true; };
  RunLoopUntil([&] { return ready; });

  std::vector<std::string> paths;
  for (auto val : files::Glob(
           fxl::StringPrintf("/hub/r/%s/*/c/appmgr_integration_tests_inspect_test_app.cmx/*/"
                             "system_diagnostics/*",
                             env_name.c_str()))) {
    paths.emplace_back(std::move(val));
  }

  ASSERT_EQ(1U, paths.size());

  fuchsia::inspect::TreePtr tree;

  fdio_service_connect(paths[0].c_str(), tree.NewRequest().TakeChannel().release());

  // Get the name of a single child.
  fuchsia::inspect::TreeNameIteratorPtr iterator;
  tree->ListChildNames(iterator.NewRequest());
  std::vector<std::string> child_names;
  iterator->GetNext([&](std::vector<std::string> names) { child_names = std::move(names); });
  RunLoopUntil([&] { return !child_names.empty(); });

  // Open the child.
  fuchsia::inspect::TreePtr child;
  bool error = false;
  child.set_error_handler([&](zx_status_t unused) { error = true; });
  tree->OpenChild(child_names[0], child.NewRequest());

  {
    // Ensure we can get the child's content.
    bool done = false;
    child->GetContent([&](fuchsia::inspect::TreeContent unused) { done = true; });
    RunLoopUntil([&] { return done || error; });
    ASSERT_FALSE(error);
  }

  // Terminate the component while holding a reference to one of the lazy nodes.
  bool terminated = false;
  controller.events().OnTerminated = [&](uint64_t status, fuchsia::sys::TerminationReason reason) {
    terminated = true;
  };
  controller->Kill();
  RunLoopUntil([&] { return terminated; });
  controller.Unbind();

  bool done = false;
  // Try to construct lazy node content. This should not succeed, but the appmgr should not crash.
  child->GetContent([&](fuchsia::inspect::TreeContent unused) { done = true; });
  RunLoopUntil([&] { return done || error; });
  EXPECT_TRUE(error);
  EXPECT_FALSE(done);
}

}  // namespace
}  // namespace component
