// 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 <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>
#include <zircon/system/ulib/zircon/include/zircon/status.h>

#include <memory>

#include "src/lib/fxl/command_line.h"
#include "src/lib/fxl/log_settings_command_line.h"
#include "src/lib/ui/base_view/view_provider_component.h"
#include "src/ui/examples/simplest_embedder/example_presenter.h"
#include "src/ui/examples/simplest_embedder/view.h"

using namespace simplest_embedder;

int main(int argc, const char** argv) {
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);

  auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
  if (!fxl::SetLogSettingsFromCommandLine(command_line))
    return 1;

  const bool kUseRootPresenter = command_line.HasOption("use_root_presenter");
  const bool kUseExamplePresenter = command_line.HasOption("use_example_presenter");
  if (kUseRootPresenter && kUseExamplePresenter) {
    FX_LOGS(ERROR) << "Cannot set both --use_root_presenter and --use_example_presenter";
    return 1;
  }

  // If the user asked us to use a Presenter, then do so.  Otherwise, just
  // provide our view as a service.
  if (kUseRootPresenter) {
    FX_LOGS(INFO) << "Using root presenter.";
    FX_LOGS(INFO) << "To quit: Tap the background and hit the ESC key.";

    // We need to attach ourselves to a Presenter. To do this, we create a
    // pair of tokens, and use one to create a View locally (which we attach
    // the rest of our UI to), and one which we pass to a Presenter to create
    // a ViewHolder to embed us.
    //
    // In the Peridot layer of Fuchsia, the device_runner both launches the
    // device shell, and connects it to the root presenter.  Here, we create
    // two eventpair handles, one of which will be passed to the root presenter
    // and the other to the View.
    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

    // Create a startup context for ourselves and use it to connect to
    // environment services.
    auto component_context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
    fuchsia::ui::scenic::ScenicPtr scenic =
        component_context->svc()->Connect<fuchsia::ui::scenic::Scenic>();
    scenic.set_error_handler([&loop](zx_status_t status) {
      FX_LOGS(ERROR) << "Lost connection to Scenic with error " << zx_status_get_string(status)
                     << ".";
      loop.Quit();
    });

    // Create a View which will launch shadertoy and attach shadertoy's View to
    // itself.
    scenic::ViewContext view_context = {
        .session_and_listener_request =
            scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
        .view_token = std::move(view_token),
        .component_context = component_context.get(),
    };
    auto view = std::make_unique<ShadertoyEmbedderView>(std::move(view_context), &loop);
    view->LaunchShadertoyClient();

    // Display the newly-created view using root_presenter.
    fidl::InterfacePtr<fuchsia::ui::policy::Presentation> presentation;
    fuchsia::ui::policy::PresenterPtr root_presenter =
        component_context->svc()->Connect<fuchsia::ui::policy::Presenter>();
    root_presenter->PresentView(std::move(view_holder_token), presentation.NewRequest());

    loop.Run();
  } else if (kUseExamplePresenter) {
    FX_LOGS(INFO) << "Using example presenter.";

    // We need to attach ourselves to a Presenter. To do this, we create a
    // pair of tokens, and use one to create a View locally (which we attach
    // the rest of our UI to), and one which we pass to a Presenter to create
    // a ViewHolder to embed us.
    //
    // In the Peridot layer of Fuchsia, the device_runner both launches the
    // device shell, and connects it to the root presenter.  Here, we create
    // two eventpair handles, one of which will be passed to our example
    // Presenter and the other to the View.
    //
    // For simplicity, both the presenter and the view run in-process, and the
    // tokens are passed to them via C++ methods.  However, it would work just
    // as well if the presenter/view lived in two other processes, and we
    // passed the tokens to them via FIDL messages.  In Peridot, this is
    // exactly what the device_runner does.
    auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();

    // Create a startup context for ourselves and use it to connect to
    // environment services.
    auto component_context = sys::ComponentContext::CreateAndServeOutgoingDirectory();
    fuchsia::ui::scenic::ScenicPtr scenic =
        component_context->svc()->Connect<fuchsia::ui::scenic::Scenic>();
    scenic.set_error_handler([&loop](zx_status_t status) {
      FX_LOGS(INFO) << "Lost connection to Scenic with error code " << status << ".";
      loop.Quit();
    });

    // Create a View which will launch shadertoy and attach shadertoy's View to
    // itself.
    scenic::ViewContext view_context = {
        .session_and_listener_request =
            scenic::CreateScenicSessionPtrAndListenerRequest(scenic.get()),
        .view_token = std::move(view_token),
        .component_context = component_context.get(),
    };
    auto view = std::make_unique<ShadertoyEmbedderView>(std::move(view_context), &loop);
    view->LaunchShadertoyClient();

    // Display the newly created View using our in-process presenter, which
    // creates a DisplayCompositor directly for screen output.
    // NOTE: The example presenter has an independent session to Scenic even
    // though it resides in the same process as the view.
    auto example_presenter = std::make_unique<ExamplePresenter>(scenic.get());
    example_presenter->PresentView(std::move(view_holder_token), nullptr);

    loop.Run();
  } else {
    // Instead of creating a View directly, provide a component that will do so
    // when asked via FIDL.
    FX_LOGS(INFO) << "Launching view provider service.";
    scenic::ViewProviderComponent component(
        [&loop](scenic::ViewContext context) {
          // Create a View which will launch shadertoy and attach shadertoy's
          // View to itself.
          auto view = std::make_unique<ShadertoyEmbedderView>(std::move(context), &loop);
          view->LaunchShadertoyClient();

          return view;
        },
        &loop);

    loop.Run();
  }

  return 0;
}
