// Copyright 2017 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/callback/scoped_callback.h>
#include <lib/component/cpp/connect.h>
#include <src/lib/fxl/memory/weak_ptr.h>
#include <lib/message_queue/cpp/message_sender_client.h>
#include <test/peridot/tests/queuepersistence/cpp/fidl.h>

#include "peridot/public/lib/integration_testing/cpp/reporting.h"
#include "peridot/public/lib/integration_testing/cpp/testing.h"
#include "peridot/tests/common/defs.h"
#include "peridot/tests/queue_persistence/defs.h"

using modular::testing::Await;
using modular::testing::Signal;
using modular::testing::TestPoint;
using namespace test::peridot::tests::queuepersistence;

namespace {

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

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

    module_host_->module_context()->GetComponentContext(
        component_context_.NewRequest());

    fuchsia::sys::ServiceProviderPtr agent_services;
    component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
                                       agent_controller_.NewRequest());
    component::ConnectToService(agent_services.get(),
                                agent_service_.NewRequest());

    Await("queue_persistence_test_agent_connected",
          [this] { AgentConnected(); });
  }

  // Called by ModuleDriver.
  TestPoint stopped_{"Root module stopped"};
  void Terminate(fit::function<void()> done) {
    stopped_.Pass();
    modular::testing::Done(std::move(done));
  }

 private:
  TestPoint agent_connected_{"fuchsia::modular::Agent accepted connection"};

  void AgentConnected() {
    agent_connected_.Pass();
    agent_service_->GetMessageQueueToken(
        [this](const fidl::StringPtr& token) { ReceivedQueueToken(token); });
  }

  TestPoint received_queue_persistence_token_{
      "Received queue_persistence token"};

  void ReceivedQueueToken(const fidl::StringPtr& token) {
    queue_token_ = token;
    received_queue_persistence_token_.Pass();

    // Stop the agent.
    agent_controller_.Unbind();
    agent_service_.Unbind();
    Await("queue_persistence_test_agent_stopped", [this] { AgentStopped(); });
  }

  TestPoint agent_stopped_{"fuchsia::modular::Agent stopped"};

  void AgentStopped() {
    agent_stopped_.Pass();

    // Send a message to the stopped agent which should be persisted to local
    // storage. No triggers are set so the agent won't be automatically started.
    modular::MessageSenderClient message_sender;
    component_context_->GetMessageSender(queue_token_,
                                         message_sender.NewRequest());
    message_sender.Send("Queued message...");

    // Start the agent again.
    fuchsia::sys::ServiceProviderPtr agent_services;
    component_context_->ConnectToAgent(kTestAgent, agent_services.NewRequest(),
                                       agent_controller_.NewRequest());
    component::ConnectToService(agent_services.get(),
                                agent_service_.NewRequest());

    Await("queue_persistence_test_agent_connected",
          [this] { AgentConnectedAgain(); });
  }

  TestPoint agent_connected_again_{
      "fuchsia::modular::Agent accepted connection, again"};

  void AgentConnectedAgain() {
    agent_connected_again_.Pass();
    Await("queue_persistence_test_agent_received_message",
          [this] { AgentReceivedMessage(); });
  }

  TestPoint agent_received_message_{"fuchsia::modular::Agent received message"};

  void AgentReceivedMessage() {
    agent_received_message_.Pass();

    // Stop the agent again.
    agent_controller_.Unbind();
    agent_service_.Unbind();
    Await("queue_persistence_test_agent_stopped",
          [this] { Signal(modular::testing::kTestShutdown); });
  }

  modular::ModuleHost* module_host_;
  fuchsia::modular::AgentControllerPtr agent_controller_;
  QueuePersistenceTestServicePtr agent_service_;
  fuchsia::modular::ComponentContextPtr component_context_;
  fuchsia::modular::MessageQueuePtr msg_queue_;

  std::string queue_token_;

  fxl::WeakPtrFactory<TestModule> weak_ptr_factory_;

  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;
}
