// 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 <fuchsia/modular/internal/cpp/fidl.h>
#include <fuchsia/modular/session/cpp/fidl.h>
#include <fuchsia/setui/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fit/defer.h>
#include <lib/fit/function.h>
#include <src/lib/fxl/command_line.h>
#include <src/lib/fxl/macros.h>
#include <trace-provider/provider.h>

#include <iostream>
#include <memory>

#include "peridot/bin/basemgr/basemgr_impl.h"
#include "peridot/bin/basemgr/basemgr_settings.h"
#include "peridot/bin/basemgr/cobalt/cobalt.h"
#include "peridot/lib/modular_config/modular_config.h"
#include "peridot/lib/modular_config/modular_config_constants.h"

namespace {
#ifdef AUTO_LOGIN_TO_GUEST
constexpr bool kAutoLoginToGuest = true;
#else
constexpr bool kAutoLoginToGuest = false;
#endif

// Base shell URL's used to implement login override. See c.f.
// ConfigureLoginOverride.
constexpr char kAutoLoginBaseShellUrl[] =
    "fuchsia-pkg://fuchsia.com/auto_login_base_shell#meta/"
    "auto_login_base_shell.cmx";

constexpr char kSingleUserBaseShellUrl[] =
    "fuchsia-pkg://fuchsia.com/single_user_base_shell#meta/"
    "single_user_base_shell.cmx";
}  // namespace

fit::deferred_action<fit::closure> SetupCobalt(
    bool enable_cobalt, async_dispatcher_t* dispatcher,
    component::StartupContext* context) {
  if (!enable_cobalt) {
    return fit::defer<fit::closure>([] {});
  }
  return modular::InitializeCobalt(dispatcher, context);
};

fuchsia::modular::session::BasemgrConfig CreateBasemgrConfigFromCommandLine(
    fxl::CommandLine command_line) {
  modular::BasemgrSettings settings(command_line);
  return settings.CreateBasemgrConfig();
}

bool LoginModeOverrideIsSpecified(
    const fuchsia::setui::SettingsObject& settings_obj,
    fuchsia::setui::LoginOverride login_override) {
  return settings_obj.data.is_account() &&
         settings_obj.data.account().has_mode() &&
         settings_obj.data.account().mode() == login_override;
}

// Configures base shell based on user specified login override.
//
// 1. Reads the login override settings stored in SetUiService.
// 2. Overrides the base shell to the base shell corresponding to the login
// override mode.
// 3. If SetUiService did not have any login override settings initially,
// write the login mode corresponding to the base shell being configured.
void ConfigureLoginOverride(fuchsia::modular::session::BasemgrConfig& config,
                            const fuchsia::setui::SettingsObject& settings_obj,
                            fuchsia::setui::SetUiService* setui) {
  // Get the login override settings. There is no scenario where both will be
  // true.
  bool auth_provider_mode_requested = LoginModeOverrideIsSpecified(
      settings_obj, fuchsia::setui::LoginOverride::AUTH_PROVIDER);
  bool guest_mode_requested = LoginModeOverrideIsSpecified(
      settings_obj, fuchsia::setui::LoginOverride::AUTOLOGIN_GUEST);

  // Any value of LoginOverride will override the build flag
  // |auto_login_to_guest|.
  if (kAutoLoginToGuest) {
    fuchsia::modular::session::AppConfig override_base_shell;
    override_base_shell.set_url(kAutoLoginBaseShellUrl);
    override_base_shell.mutable_args()->push_back("--persist_user");
    config.mutable_base_shell()->set_app_config(std::move(override_base_shell));
  }

  if (auth_provider_mode_requested) {
    FXL_LOG(INFO) << "Login Override: auth provider mode";
    // When auth provider mode is specified, we use single_user_base_shell.
    // The framework expects this package to be available in all product
    // configurations.
    fuchsia::modular::session::AppConfig override_base_shell;
    override_base_shell.set_url(kSingleUserBaseShellUrl);
    config.mutable_base_shell()->set_app_config(std::move(override_base_shell));
  } else if (guest_mode_requested) {
    FXL_LOG(INFO) << "Login Override: Guest mode";
    // When guest mode is specified, we use auto_login_base_shell with
    // a persistent guest user. The framework expects this package to be
    // available in all product configurations.
    fuchsia::modular::session::AppConfig override_base_shell;
    override_base_shell.set_url(kAutoLoginBaseShellUrl);
    override_base_shell.mutable_args()->push_back("--persist_user");
    config.mutable_base_shell()->set_app_config(std::move(override_base_shell));
  } else {
    // In the case no login mode is specified, propagate the default login mode
    // to setui service so that other components are aware of this state.
    if (settings_obj.data.is_account() &&
        settings_obj.data.account().has_mode() &&
        settings_obj.data.account().mode() !=
            fuchsia::setui::LoginOverride::NONE) {
      return;
    }

    // Determine the default login mode by looking at which base shell is being
    // used for this product configuration.
    fuchsia::setui::AccountMutation account_mutation;
    account_mutation.set_operation(
        fuchsia::setui::AccountOperation::SET_LOGIN_OVERRIDE);
    if (config.base_shell().app_config().url() == kAutoLoginBaseShellUrl) {
      account_mutation.set_login_override(
          fuchsia::setui::LoginOverride::AUTOLOGIN_GUEST);
    } else if (config.base_shell().app_config().url() ==
               kSingleUserBaseShellUrl) {
      account_mutation.set_login_override(
          fuchsia::setui::LoginOverride::AUTH_PROVIDER);
    } else {
      return;
    }

    fuchsia::setui::Mutation mutation;
    mutation.set_account_mutation_value(std::move(account_mutation));

    // There is no need to wait for this callback as the result does not
    // affect basemgr.
    setui->Mutate(
        fuchsia::setui::SettingType::ACCOUNT, std::move(mutation),
        [](fuchsia::setui::MutationResponse response) {
          if (response.return_code != fuchsia::setui::ReturnCode::OK) {
            FXL_LOG(ERROR) << "Failed to persist login type";
          }
        });
  }
}

// Configures Basemgr by passing in connected services.
std::unique_ptr<modular::BasemgrImpl> ConfigureBasemgr(
    fuchsia::modular::session::BasemgrConfig& config,
    std::shared_ptr<component::StartupContext> context, async::Loop* loop) {
  fit::deferred_action<fit::closure> cobalt_cleanup =
      SetupCobalt(config.enable_cobalt(), loop->dispatcher(), context.get());

  fuchsia::ui::policy::PresenterPtr presenter;
  context->ConnectToEnvironmentService(presenter.NewRequest());
  fuchsia::devicesettings::DeviceSettingsManagerPtr device_settings_manager;
  context->ConnectToEnvironmentService(device_settings_manager.NewRequest());
  fuchsia::wlan::service::WlanPtr wlan;
  context->ConnectToEnvironmentService(wlan.NewRequest());
  fuchsia::auth::account::AccountManagerPtr account_manager;
  context->ConnectToEnvironmentService(account_manager.NewRequest());

  return std::make_unique<modular::BasemgrImpl>(
      std::move(config), context->launcher().get(), std::move(presenter),
      std::move(device_settings_manager), std::move(wlan),
      std::move(account_manager), [&loop, &cobalt_cleanup, &context] {
        cobalt_cleanup.call();
        context->outgoing().debug_dir()->RemoveEntry(
            modular_config::kBasemgrConfigName);
        loop->Quit();
      });
}

int main(int argc, const char** argv) {
  fuchsia::modular::session::BasemgrConfig config;

  if (argc == 1) {
    // Read configurations from file if no command line arguments are passed in.
    // This sets default values for any configurations that aren't specified in
    // the configuration file.
    auto config_reader = modular::ModularConfigReader::CreateFromNamespace();
    config = config_reader.GetBasemgrConfig();

    config.mutable_sessionmgr()->set_url(modular_config::kSessionmgrUrl);
    config.mutable_sessionmgr()->set_args({});
  } else {
    // Read command line arguments
    auto command_line = fxl::CommandLineFromArgcArgv(argc, argv);
    if (command_line.HasOption("help")) {
      std::cout << modular::BasemgrSettings::GetUsage() << std::endl;
      return 0;
    }

    config = CreateBasemgrConfigFromCommandLine(command_line);
  }

  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  trace::TraceProvider trace_provider(loop.dispatcher());
  auto context = std::shared_ptr<component::StartupContext>(
      component::StartupContext::CreateFromStartupInfo());

  fuchsia::setui::SetUiServicePtr setui;
  std::unique_ptr<modular::BasemgrImpl> basemgr_impl;
  auto initialize_basemgr =
      [&config, &loop, &context, &basemgr_impl, &setui,
       ran = false](fuchsia::setui::SettingsObject settings_obj) mutable {
        if (ran) {
          return;
        }

        ran = true;

        ConfigureLoginOverride(config, settings_obj, setui.get());

        std::unique_ptr<modular::BasemgrImpl> basemgr =
            ConfigureBasemgr(config, context, &loop);

        basemgr_impl = std::move(basemgr);

        context->outgoing().debug_dir()->AddEntry(
            modular_config::kBasemgrConfigName,
            fbl::AdoptRef(new fs::Service([basemgr_impl = basemgr_impl.get()](
                                              zx::channel channel) {
              fidl::InterfaceRequest<fuchsia::modular::internal::BasemgrDebug>
                  request(std::move(channel));
              basemgr_impl->Connect(std::move(request));
              return ZX_OK;
            })));
      };

  setui.set_error_handler([&initialize_basemgr](zx_status_t status) {
    // In case of error, log event and continue as if no user setting is
    // present.
    FXL_LOG(ERROR) << "Error retrieving user set login override, defaulting to "
                      "build time configuration";
    fuchsia::setui::AccountSettings default_account_settings;
    default_account_settings.set_mode(fuchsia::setui::LoginOverride::NONE);
    fuchsia::setui::SettingsObject default_settings_object;
    default_settings_object.setting_type = fuchsia::setui::SettingType::ACCOUNT;
    default_settings_object.data.set_account(
        std::move(default_account_settings));

    initialize_basemgr(std::move(default_settings_object));
  });

  context->ConnectToEnvironmentService(setui.NewRequest());

  // Retrieve the user specified login override. This override will take
  // precedence over any compile time configuration. Watch will always
  // return a value in this case, as it is the initial request (long
  // polling).
  setui->Watch(fuchsia::setui::SettingType::ACCOUNT, initialize_basemgr);

  loop.Run();

  return 0;
}
