// Copyright 2016 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 <set>
#include <utility>

#include <fuchsia/modular/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/policy/cpp/fidl.h>
#include <fuchsia/ui/viewsv1token/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/fxl/command_line.h>
#include <lib/fxl/logging.h>
#include <lib/fxl/macros.h>
#include <lib/fxl/tasks/task_runner.h>
#include <lib/fxl/time/time_delta.h>

#include "peridot/lib/common/names.h"
#include "peridot/lib/fidl/clone.h"
#include "peridot/lib/rapidjson/rapidjson.h"
#include "peridot/lib/testing/component_main.h"
#include "peridot/lib/testing/session_shell_base.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/story_shell/defs.h"

using modular::testing::Get;
using modular::testing::Put;
using modular::testing::Signal;
using modular::testing::TestPoint;

namespace {

const char kStoryName1[] = "story1";
const char kStoryName2[] = "story2";

// Cf. README.md for what this test does and how.
class TestApp : public modular::testing::SessionShellBase,
                fuchsia::modular::SessionShellPresentationProvider {
 public:
  explicit TestApp(component::StartupContext* const startup_context)
      : SessionShellBase(startup_context) {
    TestInit(__FILE__);

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

    startup_context->outgoing()
        .AddPublicService<fuchsia::modular::SessionShellPresentationProvider>(
            [this](fidl::InterfaceRequest<
                   fuchsia::modular::SessionShellPresentationProvider>
                       request) {
              presentation_provider_bindings_.AddBinding(this,
                                                         std::move(request));
            });

    Story1_Create();
  }

  ~TestApp() override = default;

 private:
  TestPoint story1_presentation_request_{"Story1 Presentation request"};
  bool story1_presentation_request_received_{};

  TestPoint story2_presentation_request_{"Story2 Presentation request"};
  bool story2_presentation_request_received_{};

  // |fuchsia::modular::SessionShellPresentationProvider|
  void GetPresentation(std::string story_id,
                       fidl::InterfaceRequest<fuchsia::ui::policy::Presentation>
                           request) override {
    if (story_id == kStoryName1 && !story1_presentation_request_received_) {
      story1_presentation_request_.Pass();
      story1_presentation_request_received_ = true;
    }

    if (story_id == kStoryName2 && !story2_presentation_request_received_) {
      story2_presentation_request_.Pass();
      story2_presentation_request_received_ = true;
    }

    MaybeLogout();
  }

  // |fuchsia::modular::SessionShellPresentationProvider|
  void WatchVisualState(
      std::string story_id,
      fidl::InterfaceHandle<fuchsia::modular::StoryVisualStateWatcher> watcher)
      override {}

  TestPoint create_view_{"CreateView()"};

  // |SingleServiceApp|
  void CreateView(
      zx::eventpair /*view_token*/,
      fidl::InterfaceRequest<
          fuchsia::sys::ServiceProvider> /*incoming_services*/,
      fidl::InterfaceHandle<
          fuchsia::sys::ServiceProvider> /*outgoing_services*/) override {
    create_view_.Pass();
  }

  TestPoint story1_create_{"Story1 Create"};

  void Story1_Create() {
    std::vector<fuchsia::modular::StoryCommand> commands;
    auto addMod = [&commands](fidl::StringPtr name,
                              std::vector<fidl::StringPtr> parent) {
      fuchsia::modular::AddMod add_mod;
      add_mod.mod_name_transitional = name;
      add_mod.intent.action = kCommonNullAction;
      add_mod.intent.handler = kCommonNullModule;

      for (auto i : parent) {
        add_mod.surface_parent_mod_name.push_back(i);
      }

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

    addMod("root", {});
    addMod("one", {"root"});
    addMod("two", {"root", "one"});

    puppet_master_->ControlStory(kStoryName1,
                                 story_puppet_master_.NewRequest());
    story_puppet_master_->Enqueue(std::move(commands));
    story_puppet_master_->Execute(
        [this](fuchsia::modular::ExecuteResult result) {
          story1_create_.Pass();
          Story1_Run1();
        });
  }

  TestPoint story1_run1_{"Story1 Run1"};

  void Story1_Run1() {
    story_provider()->GetController(kStoryName1,
                                    story_controller_.NewRequest());

    // TODO(jphsiao|vardhan): remodel this |proceed_after_6| style of
    // continuation to use Futures instead.
    auto proceed_after_6 = modular::testing::NewBarrierClosure(6, [this] {
      story1_run1_.Pass();
      Story1_Stop1();
    });

    Get("story link data: null", proceed_after_6);
    Get("root:one", proceed_after_6);
    Get("root:one manifest", proceed_after_6);
    Get("root:one:two", proceed_after_6);
    Get("root:one:two manifest", proceed_after_6);
    Get("root:one:two ordering", proceed_after_6);

    story_controller_->RequestStart();
  }

  void Story1_Stop1() {
    story_controller_->Stop([this] { Story1_Run2(); });
  }

  TestPoint story1_run2_{"Story1 Run2"};

  void Story1_Run2() {
    auto proceed_after_6 = modular::testing::NewBarrierClosure(6, [this] {
      story1_run2_.Pass();
      Story1_Stop2();
    });

    Get("story link data: {\"label\":\"value\"}", proceed_after_6);
    Get("root:one", proceed_after_6);
    Get("root:one manifest", proceed_after_6);
    Get("root:one:two", proceed_after_6);
    Get("root:one:two manifest", proceed_after_6);
    Get("root:one:two ordering", proceed_after_6);

    story_controller_->RequestStart();
  }

  void Story1_Stop2() {
    story_controller_->Stop([this] { Story2_Create(); });
  }

  // We do the same sequence with Story2 that we did for Story1, except that the
  // modules are started with packages rather than actions in their Intents.

  TestPoint story2_create_{"Story2 Create"};

  void Story2_Create() {
    std::vector<fuchsia::modular::StoryCommand> commands;
    auto addMod = [&commands](fidl::StringPtr name,
                              std::vector<fidl::StringPtr> parent) {
      fuchsia::modular::AddMod add_mod;
      add_mod.mod_name_transitional = name;
      add_mod.intent.action = kCommonNullAction;
      add_mod.intent.handler = kCommonNullModule;

      for (auto i : parent) {
        add_mod.surface_parent_mod_name.push_back(i);
      }

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

    addMod("root", {});
    addMod("one", {"root"});
    addMod("two", {"root", "one"});

    puppet_master_->ControlStory(kStoryName2,
                                 story_puppet_master_.NewRequest());
    story_puppet_master_->Enqueue(std::move(commands));
    story_puppet_master_->Execute(
        [this](fuchsia::modular::ExecuteResult result) {
          story2_create_.Pass();
          Story2_Run1();
        });
  }

  TestPoint story2_run1_{"Story2 Run1"};

  void Story2_Run1() {
    auto proceed_after_5 = modular::testing::NewBarrierClosure(5, [this] {
      story2_run1_.Pass();
      Story2_Stop1();
    });

    Get("root:one", proceed_after_5);
    Get("root:one manifest", proceed_after_5);
    Get("root:one:two", proceed_after_5);
    Get("root:one:two manifest", proceed_after_5);
    Get("root:one:two ordering", proceed_after_5);

    story_provider()->GetController(kStoryName2,
                                    story_controller_.NewRequest());
    story_controller_->RequestStart();
  }

  void Story2_Stop1() {
    story_controller_->Stop([this] { Story2_Run2(); });
  }

  TestPoint story2_run2_{"Story2 Run2"};

  void Story2_Run2() {
    auto proceed_after_5 = modular::testing::NewBarrierClosure(5, [this] {
      story2_run2_.Pass();
      Story2_Stop2();
    });

    Get("root:one", proceed_after_5);
    Get("root:one manifest", proceed_after_5);
    Get("root:one:two", proceed_after_5);
    Get("root:one:two manifest", proceed_after_5);
    Get("root:one:two ordering", proceed_after_5);

    story_controller_->RequestStart();
  }

  bool end_of_story2_{};

  void Story2_Stop2() {
    story_controller_->Stop([this] {
      end_of_story2_ = true;
      MaybeLogout();
    });
  }

  void MaybeLogout() {
    if (story1_presentation_request_received_ &&
        story2_presentation_request_received_ && end_of_story2_) {
      Signal(modular::testing::kTestShutdown);
    }
  }

  fuchsia::modular::PuppetMasterPtr puppet_master_;
  fuchsia::modular::StoryPuppetMasterPtr story_puppet_master_;
  fuchsia::modular::StoryControllerPtr story_controller_;
  fidl::BindingSet<fuchsia::modular::SessionShellPresentationProvider>
      presentation_provider_bindings_;

  FXL_DISALLOW_COPY_AND_ASSIGN(TestApp);
};

}  // namespace

int main(int /* argc */, const char** /* argv */) {
  modular::testing::ComponentMain<TestApp>();
  return 0;
}
