// 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/modular/cpp/fidl.h>
#include <lib/app_driver/cpp/module_driver.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/component/cpp/connect.h>
#include <lib/fsl/vmo/strings.h>
#include <test/peridot/tests/trigger/cpp/fidl.h>

#include "peridot/lib/rapidjson/rapidjson.h"
#include "peridot/public/lib/integration_testing/cpp/reporting.h"
#include "peridot/public/lib/integration_testing/cpp/testing.h"
#include "peridot/tests/module_context/defs.h"

using ::modular::testing::Await;
using ::modular::testing::Signal;
using ::modular::testing::TestPoint;
using ::test::peridot::tests::trigger::TriggerTestServicePtr;

namespace {

// Cf. README.md for what this test does and how.
class TestModule {
 public:
  TestPoint initialized_{"Root module initialized"};

  TestModule(modular::ModuleHost* const module_host,
             fidl::InterfaceRequest<
                 fuchsia::ui::app::ViewProvider> /*view_provider_request*/) {
    modular::testing::Init(module_host->startup_context(), __FILE__);
    fuchsia::modular::ModuleContext* module_context =
        module_host->module_context();
    initialized_.Pass();

    module_host->module_context()->GetLink(kLinkName, link_.NewRequest());
    fidl::VectorPtr<std::string> name;
    name.push_back(kLinkKey);
    link_->Get(name.Clone(), [this, module_context](
                                 std::unique_ptr<fuchsia::mem::Buffer> value) {
      if (!value) {
        modular::testing::Fail("Did not receive a module name in link.");
        return;
      }

      std::string value_string;
      FXL_CHECK(fsl::StringFromVmo(*value, &value_string));

      rapidjson::Document document;
      document.Parse(value_string.c_str());
      module_name_ = document.GetString();

      Await(module_name_ == kFirstModuleName ? kFirstModuleCallDone
                                             : kSecondModuleCallDone,
            [this, module_context] { module_context->RemoveSelfFromStory(); });
      Await(module_name_ == kFirstModuleName ? kFirstModuleCallStartActivity
                                             : kSecondModuleCallStartActivity,
            [this, module_context] {
              module_context->StartOngoingActivity(
                  fuchsia::modular::OngoingActivityType::VIDEO,
                  ongoing_activity_.NewRequest());
            });
      Await(module_name_ == kFirstModuleName ? kFirstModuleCallStopActivity
                                             : kSecondModuleCallStopActivity,
            [this, module_context] { ongoing_activity_.Unbind(); });
    });
  }

  TestModule(modular::ModuleHost* const module_host,
             fidl::InterfaceRequest<
                 fuchsia::ui::viewsv1::ViewProvider> /*view_provider_request*/)
      : TestModule(
            module_host,
            fidl::InterfaceRequest<fuchsia::ui::app::ViewProvider>(nullptr)) {}

  // Called by ModuleDriver.
  TestPoint stopped_{"Root module stopped"};
  void Terminate(const std::function<void()>& done) {
    stopped_.Pass();
    std::string terminated = module_name_ == kFirstModuleName
                                 ? kFirstModuleTerminated
                                 : kSecondModuleTerminated;
    Signal(terminated);
    modular::testing::Done(done);
  }

 private:
  fuchsia::modular::LinkPtr link_;
  std::string module_name_ = "";
  fuchsia::modular::OngoingActivityPtr ongoing_activity_;

  FXL_DISALLOW_COPY_AND_ASSIGN(TestModule);
};

}  // namespace

int main(int /*argc*/, const char** /*argv*/) {
  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  auto context = component::StartupContext::CreateFromStartupInfo();
  modular::ModuleDriver<TestModule> driver(context.get(),
                                           [&loop] { loop.Quit(); });
  loop.Run();
  return 0;
}
