// 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/fsl/vmo/strings.h>
#include <lib/modular_test_harness/cpp/test_harness_fixture.h>
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>

namespace modular {
namespace testing {
namespace {

const char kTestHarnessUrl[] =
    "fuchsia-pkg://fuchsia.com/modular_test_harness#meta/"
    "modular_test_harness.cmx";

std::string BuildExtraCmx(TestHarnessBuilder::InterceptOptions options) {
  if (options.sandbox_services.empty())
    return "";

  rapidjson::Document cmx;
  cmx.SetObject();
  rapidjson::Value sandbox;
  sandbox.SetObject();
  rapidjson::Value services;
  services.SetArray();
  for (const auto& service : options.sandbox_services) {
    rapidjson::Value v(service, cmx.GetAllocator());
    services.PushBack(v.Move(), cmx.GetAllocator());
  }
  sandbox.AddMember("services", services.Move(), cmx.GetAllocator());
  cmx.AddMember("sandbox", sandbox.Move(), cmx.GetAllocator());

  rapidjson::StringBuffer buf;
  rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
  cmx.Accept(writer);
  return buf.GetString();
}

bool BufferFromString(std::string str, fuchsia::mem::Buffer* buffer) {
  ZX_ASSERT(buffer != nullptr);
  uint64_t num_bytes = str.size();
  zx::vmo vmo;
  zx_status_t status = zx::vmo::create(num_bytes, 0u, &vmo);
  if (status < 0) {
    return false;
  }

  if (num_bytes > 0) {
    status = vmo.write(str.data(), 0, num_bytes);
    if (status < 0) {
      return false;
    }
  }

  buffer->vmo = std::move(vmo);
  buffer->size = num_bytes;
  return true;
}

}  // namespace

fuchsia::modular::testing::TestHarnessSpec TestHarnessBuilder::BuildSpec() {
  return std::move(spec_);
}

TestHarnessBuilder::OnNewComponentHandler
TestHarnessBuilder::BuildOnNewComponentHandler() {
  return
      [handlers = std::move(handlers_)](
          fuchsia::sys::StartupInfo startup_info,
          fidl::InterfaceHandle<fuchsia::modular::testing::InterceptedComponent>
              component) {
        auto it = handlers.find(startup_info.launch_info.url);
        if (it == handlers.end()) {
          ZX_ASSERT_MSG(false, "Unexpected component URL: %s",
                        startup_info.launch_info.url.c_str());
        }

        it->second(std::move(startup_info), component.Bind());
      };
}

TestHarnessBuilder& TestHarnessBuilder::InterceptComponent(
    OnNewComponentHandler on_new_component, InterceptOptions options) {
  ZX_ASSERT(on_new_component);
  if (options.url.empty()) {
    options.url = GenerateFakeUrl();
  }

  fuchsia::modular::testing::InterceptSpec intercept_spec;
  intercept_spec.set_component_url(options.url);
  auto extra_cmx_contents = BuildExtraCmx(options);
  if (!extra_cmx_contents.empty()) {
    ZX_ASSERT(BufferFromString(extra_cmx_contents,
                               intercept_spec.mutable_extra_cmx_contents()));
  }
  spec_.mutable_components_to_intercept()->push_back(std::move(intercept_spec));

  handlers_.insert(std::make_pair(options.url, std::move(on_new_component)));
  return *this;
}

TestHarnessBuilder& TestHarnessBuilder::InterceptBaseShell(
    OnNewComponentHandler on_new_component, InterceptOptions options) {
  if (options.url.empty()) {
    options.url = GenerateFakeUrl();
  }
  auto url = options.url;
  InterceptComponent(std::move(on_new_component), std::move(options));

  spec_.mutable_basemgr_config()
      ->mutable_base_shell()
      ->mutable_app_config()
      ->set_url(url);
  return *this;
}

TestHarnessBuilder& TestHarnessBuilder::InterceptSessionShell(
    OnNewComponentHandler on_new_component, InterceptOptions options) {
  if (options.url.empty()) {
    options.url = GenerateFakeUrl();
  }
  auto url = options.url;
  InterceptComponent(std::move(on_new_component), std::move(options));

  fuchsia::modular::session::SessionShellMapEntry entry;
  entry.mutable_config()->mutable_app_config()->set_url(url);
  spec_.mutable_basemgr_config()->mutable_session_shell_map()->push_back(
      std::move(entry));
  return *this;
}

TestHarnessBuilder& TestHarnessBuilder::InterceptStoryShell(
    OnNewComponentHandler on_new_component, InterceptOptions options) {
  if (options.url.empty()) {
    options.url = GenerateFakeUrl();
  }
  auto url = options.url;
  InterceptComponent(std::move(on_new_component), std::move(options));

  spec_.mutable_basemgr_config()
      ->mutable_story_shell()
      ->mutable_app_config()
      ->set_url(url);
  return *this;
}

std::string TestHarnessBuilder::GenerateFakeUrl() const {
  uint32_t random_number = 0;
  zx_cprng_draw(&random_number, sizeof random_number);
  std::string rand_str = std::to_string(random_number);

  // Since we cannot depend on utlitites outside of the stdlib and SDK, here
  // is a quick way to format a string safely.
  std::string url;
  url = "fuchsia-pkg://example.com/GENERATED_URL_";
  url += rand_str;
  url += "#meta/GENERATED_URL_";
  url += rand_str;
  url += ".cmx";

  return url;
}

TestHarnessFixture::~TestHarnessFixture() = default;

std::string TestHarnessFixture::InterceptBaseShell(
    fuchsia::modular::testing::TestHarnessSpec* spec) const {
  auto url = TestHarnessBuilder().GenerateFakeUrl();
  spec->mutable_basemgr_config()
      ->mutable_base_shell()
      ->mutable_app_config()
      ->set_url(url);

  fuchsia::modular::testing::InterceptSpec intercept_spec;
  intercept_spec.set_component_url(url);
  spec->mutable_components_to_intercept()->push_back(std::move(intercept_spec));

  return url;
}

std::string TestHarnessFixture::InterceptSessionShell(
    fuchsia::modular::testing::TestHarnessSpec* spec,
    std::string extra_cmx_contents) const {
  auto url = TestHarnessBuilder().GenerateFakeUrl();

  // 1. Add session shell to modular config.
  {
    fuchsia::modular::session::SessionShellMapEntry entry;
    entry.mutable_config()->mutable_app_config()->set_url(url);

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

  // 2. Set up interception for session shell.
  fuchsia::modular::testing::InterceptSpec shell_intercept_spec;
  if (!extra_cmx_contents.empty()) {
    ZX_ASSERT(BufferFromString(
        extra_cmx_contents, shell_intercept_spec.mutable_extra_cmx_contents()));
  }
  shell_intercept_spec.set_component_url(url);
  spec->mutable_components_to_intercept()->push_back(
      std::move(shell_intercept_spec));

  return url;
}

std::string TestHarnessFixture::InterceptStoryShell(
    fuchsia::modular::testing::TestHarnessSpec* spec) const {
  auto url = TestHarnessBuilder().GenerateFakeUrl();
  spec->mutable_basemgr_config()
      ->mutable_story_shell()
      ->mutable_app_config()
      ->set_url(url);

  fuchsia::modular::testing::InterceptSpec intercept_spec;
  intercept_spec.set_component_url(url);
  spec->mutable_components_to_intercept()->push_back(std::move(intercept_spec));

  return url;
}

TestHarnessFixture::TestHarnessFixture() {
  fuchsia::sys::LaunchInfo launch_info;
  launch_info.url = kTestHarnessUrl;
  svc_ =
      sys::ServiceDirectory::CreateWithRequest(&launch_info.directory_request);
  launcher_ptr()->CreateComponent(std::move(launch_info),
                                  test_harness_ctrl_.NewRequest());

  test_harness_ = svc_->Connect<fuchsia::modular::testing::TestHarness>();
}

}  // namespace testing
}  // namespace modular
