// 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 <memory>
#include <utility>

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/default.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fsl/vmo/strings.h>
#include <src/lib/fxl/command_line.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/macros.h>
#include <src/lib/fxl/strings/string_number_conversions.h>
#include <trace-provider/provider.h>
#include <trace/event.h>
#include <trace/observer.h>

#include "peridot/lib/fidl/single_service_app.h"
#include "peridot/lib/testing/component_main.h"
#include "peridot/lib/testing/session_shell_impl.h"
#include "peridot/public/lib/integration_testing/cpp/reporting.h"
#include "peridot/public/lib/integration_testing/cpp/testing.h"
#include "peridot/tests/benchmarks/story/tracing_waiter.h"

namespace {

const char kStoryNamePrefix[] = "story-";
const char kRootModuleName[] = "root";

class Settings {
 public:
  explicit Settings(const fxl::CommandLine& command_line) {
    const auto story_count_str =
        command_line.GetOptionValueWithDefault("story_count", "1");
    if (!fxl::StringToNumberWithError(story_count_str, &story_count)) {
      FXL_LOG(ERROR) << "Unrecognized value [--story_count=" << story_count_str
                     << "]: Using 0.";
    }

    module_url = command_line.GetOptionValueWithDefault(
        "module_url",
        "fuchsia-pkg://fuchsia.com/modular_benchmark_story_module#meta/"
        "modular_benchmark_story_module.cmx");
  }

  int story_count{0};
  std::string module_url;
};

// A simple story watcher implementation that invokes a "continue" callback when
// it sees the watched story transition to the given state. Used to push the
// test sequence forward when the test story reaches the next state.
class StoryWatcherImpl : fuchsia::modular::StoryWatcher {
 public:
  StoryWatcherImpl() : binding_(this) {}
  ~StoryWatcherImpl() override = default;

  // Registers itself as a watcher on the given story. Only one story at a time
  // can be watched.
  void Watch(fuchsia::modular::StoryController* const story_controller) {
    story_controller->Watch(binding_.NewBinding());
  }

  // Deregisters itself from the watched story.
  void Reset() { binding_.Unbind(); }

  // Sets the function where to continue when the story is observed to be done.
  void Continue(fuchsia::modular::StoryState state, fit::function<void()> at) {
    continue_state_ = state;
    continue_ = std::move(at);
  }

 private:
  // |fuchsia::modular::StoryWatcher|
  void OnStateChange(fuchsia::modular::StoryState state) override {
    if (state != continue_state_) {
      return;
    }

    continue_();
  }

  // |fuchsia::modular::StoryWatcher|
  void OnModuleAdded(fuchsia::modular::ModuleData module_data) override {}

  // |fuchsia::modular::StoryWatcher|
  void OnModuleFocused(std::vector<std::string> module_path) override {}

  fidl::Binding<fuchsia::modular::StoryWatcher> binding_;

  fuchsia::modular::StoryState continue_state_{
      fuchsia::modular::StoryState::STOPPED};
  fit::function<void()> continue_{[] {}};

  FXL_DISALLOW_COPY_AND_ASSIGN(StoryWatcherImpl);
};

// A simple link watcher implementation that invokes a "continue" callback when
// it sees the watched link change.
class LinkWatcherImpl : fuchsia::modular::LinkWatcher {
 public:
  LinkWatcherImpl() : binding_(this) {}
  ~LinkWatcherImpl() override = default;

  // Registers itself as a watcher on the given link. Only one story at a time
  // can be watched.
  void Watch(fuchsia::modular::Link* const link) {
    link->WatchAll(binding_.NewBinding());
  }

  // Deregisters itself from the watched story.
  void Reset() { binding_.Unbind(); }

  // Sets the function where to continue when the story is observed to be done.
  void Continue(fit::function<void(fidl::StringPtr)> at) {
    continue_ = std::move(at);
  }

 private:
  // |fuchsia::modular::LinkWatcher|
  void Notify(fuchsia::mem::Buffer value) override {
    std::string json;
    FXL_CHECK(fsl::StringFromVmo(value, &json));
    continue_(json);
  }

  fidl::Binding<fuchsia::modular::LinkWatcher> binding_;

  fit::function<void(fidl::StringPtr)> continue_{[](fidl::StringPtr) {}};

  FXL_DISALLOW_COPY_AND_ASSIGN(LinkWatcherImpl);
};

// Measures timing the machinery available to a session shell implementation.
// This is invoked as a session shell from basemgr and executes a predefined
// sequence of steps, rather than to expose a UI to be driven by user
// interaction, as a session shell normally would.
class TestApp : public modular::ViewApp {
 public:
  TestApp(component::StartupContext* const startup_context, Settings settings)
      : ViewApp(startup_context), settings_(std::move(settings)) {
    startup_context->ConnectToEnvironmentService(
        session_shell_context_.NewRequest());
    session_shell_context_->GetStoryProvider(story_provider_.NewRequest());

    startup_context->ConnectToEnvironmentService(puppet_master_.NewRequest());

    startup_context->outgoing().AddPublicService(
        session_shell_impl_.GetHandler());

    tracing_waiter_.WaitForTracing([this] { Loop(); });
  }

  ~TestApp() override = default;

  // Called by AppDriver in ComponentMain(). NOTE(mesch): Even though it
  // overrides SingleServiceApp::Terminate(), it is called directly on TestApp
  // by AppDriver, so it must not be private.
  void Terminate(fit::function<void()> done) override {
    // The corresponding BEGIN() call is in Loop(), below.
    TRACE_ASYNC_END("benchmark", "user/logout", 0);
    done();
  }

 private:
  void Loop() {
    if (story_count_ < settings_.story_count) {
      FXL_LOG(INFO) << "Loop at " << story_count_ << " of "
                    << settings_.story_count;
      async::PostTask(async_get_default_dispatcher(),
                      [this] { StoryCreate(); });

    } else {
      TRACE_ASYNC_BEGIN("benchmark", "user/logout", 0);
      session_shell_context_->Logout();
    }
  }

  void StoryCreate() {
    FXL_LOG(INFO) << "StoryCreate()";
    TRACE_ASYNC_BEGIN("benchmark", "story/create", 0);
    std::string story_name =
        std::string(kStoryNamePrefix) + std::to_string(story_count_);
    puppet_master_->ControlStory(story_name, story_puppet_master_.NewRequest());

    std::vector<fuchsia::modular::StoryCommand> commands;
    fuchsia::modular::AddMod add_mod;
    add_mod.mod_name_transitional = "root";
    add_mod.intent.handler = settings_.module_url;
    add_mod.intent.action = "action";

    fuchsia::modular::StoryCommand command;
    command.set_add_mod(std::move(add_mod));
    commands.push_back(std::move(command));

    story_puppet_master_->Enqueue(std::move(commands));
    story_puppet_master_->Execute(
        [this, story_name](fuchsia::modular::ExecuteResult result) {
          TRACE_ASYNC_END("benchmark", "story/create", 0);
          StoryInfo(story_name);
        });
  }

  void StoryInfo(fidl::StringPtr story_id) {
    FXL_LOG(INFO) << "StoryInfo()";
    story_provider_->GetController(story_id, story_controller_.NewRequest());

    TRACE_ASYNC_BEGIN("benchmark", "story/info", 0);
    story_controller_->GetInfo([this](fuchsia::modular::StoryInfo story_info,
                                      fuchsia::modular::StoryState state) {
      TRACE_ASYNC_END("benchmark", "story/info", 0);
      Link();
    });
  }

  void Link() {
    FXL_LOG(INFO) << "Link()";

    fuchsia::modular::LinkPath link_path = fuchsia::modular::LinkPath();
    std::vector<std::string> root_module_path;
    root_module_path.push_back(kRootModuleName);
    link_path.module_path = std::move(root_module_path);
    link_path.link_name = nullptr;
    story_controller_->GetLink(std::move(link_path), link_.NewRequest());

    link_watcher_.Watch(link_.get());
    link_watcher_.Continue([this](fidl::StringPtr json) {
      FXL_LOG(INFO) << "Link() Watch: " << json;
      if (json == "") {
        return;
      }

      const int count = fxl::StringToNumber<int>(json.get());

      // Corresponding TRACE_FLOW_BEGIN() is in the module.
      TRACE_FLOW_END("benchmark", "link/trans", count);

      if (count == 100) {
        StoryStop();
      }
    });

    StoryStart();
  }

  void StoryStart() {
    FXL_LOG(INFO) << "StoryStart()";
    TRACE_ASYNC_BEGIN("benchmark", "story/start", 0);
    story_watcher_.Continue(fuchsia::modular::StoryState::RUNNING, [this] {
      TRACE_ASYNC_END("benchmark", "story/start", 0);
    });

    story_watcher_.Watch(story_controller_.get());
    story_controller_->RequestStart();
  }

  void StoryStop() {
    FXL_LOG(INFO) << "StoryStop()";
    TRACE_ASYNC_BEGIN("benchmark", "story/stop", 0);
    story_controller_->Stop([this] {
      TRACE_ASYNC_END("benchmark", "story/stop", 0);
      MaybeRepeat();
    });
  }

  void MaybeRepeat() {
    FXL_LOG(INFO) << "MaybeRepeat()";
    story_watcher_.Reset();
    story_controller_.Unbind();

    story_count_++;
    Loop();
  }

  modular::TracingWaiter tracing_waiter_;

  const Settings settings_;

  int story_count_{};

  StoryWatcherImpl story_watcher_;
  LinkWatcherImpl link_watcher_;
  modular::testing::SessionShellImpl session_shell_impl_;

  fuchsia::modular::PuppetMasterPtr puppet_master_;
  fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;

  fuchsia::modular::SessionShellContextPtr session_shell_context_;
  fuchsia::modular::StoryProviderPtr story_provider_;
  fuchsia::modular::StoryControllerPtr story_controller_;
  fuchsia::modular::LinkPtr link_;

  FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
};

}  // namespace

int main(int argc, const char** argv) {
  auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  Settings settings(command_line);
  modular::testing::ComponentMain<TestApp, Settings>(std::move(settings));
  return 0;
}
