// 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.

#ifndef PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_
#define PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_

#include <fuchsia/auth/cpp/fidl.h>
#include <fuchsia/modular/auth/cpp/fidl.h>
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/async/cpp/future.h>
#include <lib/component/cpp/startup_context.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/fidl/cpp/interface_request.h>

#include "peridot/bin/basemgr/user_controller_impl.h"

namespace fuchsia {
namespace modular {
struct UsersStorage;
}
}  // namespace fuchsia

namespace modular {

class UserProviderImpl : fuchsia::auth::AuthenticationContextProvider,
                         fuchsia::modular::UserProvider {
 public:
  // Users of UserProviderImpl must register a Delegate object.
  class Delegate {
   public:
    // Called after UserProviderImpl successfully logs in a user.
    virtual void DidLogin() = 0;

    // Called after UserProviderImpl successfully logs out a user.
    virtual void DidLogout() = 0;

    // Enables the delegate to intercept the session shell's view owner, so that
    // e.g. the delegate can embed it in a parent view or present it.
    // |default_view_owner| is the view owner request that's passed to
    // UserProviderImpl from base shell. If you don't need to intercept the
    // view owner, return it without modifying it.
    virtual fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
    GetSessionShellViewOwner(
        fidl::InterfaceRequest<fuchsia::ui::viewsv1token::ViewOwner>
            default_view_owner) = 0;

    // Enables the delegate to supply a different service provider to the user
    // shell. |default_service_provider| is the service provider passed to the
    // session shell by the base shell. If you don't need to replace it, return
    // it without modifying it.
    virtual fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
    GetSessionShellServiceProvider(
        fidl::InterfaceHandle<fuchsia::sys::ServiceProvider>
            default_service_provider) = 0;
  };

  // |account_provider| and |delegate| must outlive UserProviderImpl.
  UserProviderImpl(
      fuchsia::sys::Launcher* const launcher,
      const fuchsia::modular::AppConfig& sessionmgr,
      const fuchsia::modular::AppConfig& session_shell,
      const fuchsia::modular::AppConfig& story_shell,
      fuchsia::auth::TokenManagerFactory* token_manager_factory,
      fuchsia::auth::AuthenticationContextProviderPtr auth_context_provider,
      Delegate* const delegate);

  void Connect(fidl::InterfaceRequest<fuchsia::modular::UserProvider> request);

  void Teardown(const std::function<void()>& callback);

  // Stops the active session shell, and starts the session shell specified in
  // |session_shell_config|. This has no effect, and will return an
  // immediately-completed future, if no session shells are running.
  FuturePtr<> SwapSessionShell(
      fuchsia::modular::AppConfig session_shell_config);

  // Restarts the current session by logging out the current user and logging
  // that user back in.
  void RestartSession();

  // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
  void Login(fuchsia::modular::UserLoginParams params) override;

  // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
  void PreviousUsers(PreviousUsersCallback callback) override;

  // |fuchsia::modular::UserProvider|, also called by |basemgr_impl|.
  void RemoveUser(fidl::StringPtr account_id,
                  RemoveUserCallback callback) override;

 private:
  // |fuchsia::modular::UserProvider|
  void AddUser(fuchsia::modular::auth::IdentityProvider identity_provider,
               AddUserCallback callback) override;

  // |fuchsia::auth::AuthenticationContextProvider|
  void GetAuthenticationUIContext(
      fidl::InterfaceRequest<fuchsia::auth::AuthenticationUIContext> request)
      override;

  // Returns a new |fuchsia::auth::TokenManager| handle for the given user
  // account |account_id|.
  fuchsia::auth::TokenManagerPtr CreateTokenManager(fidl::StringPtr account_id);

  bool AddUserToAccountsDB(const fuchsia::modular::auth::Account* account,
                           std::string* error);
  bool RemoveUserFromAccountsDB(fidl::StringPtr account_id, std::string* error);
  bool WriteUsersDb(const std::string& serialized_users, std::string* error);
  bool Parse(const std::string& serialized_users);
  void RemoveUserInternal(fuchsia::modular::auth::AccountPtr account,
                          RemoveUserCallback callback);
  void LoginInternal(fuchsia::modular::auth::AccountPtr account,
                     fuchsia::modular::UserLoginParams params);

  fidl::BindingSet<fuchsia::modular::UserProvider> bindings_;

  fuchsia::sys::Launcher* const launcher_;         // Not owned.
  const fuchsia::modular::AppConfig& sessionmgr_;  // Neither owned nor copied.
  const fuchsia::modular::AppConfig&
      session_shell_;                               // Neither owned nor copied.
  const fuchsia::modular::AppConfig& story_shell_;  // Neither owned nor copied.
  fuchsia::auth::TokenManagerFactory* const
      token_manager_factory_;  // Neither owned nor copied.
  fuchsia::auth::AuthenticationContextProviderPtr
      authentication_context_provider_;
  Delegate* const delegate_;  // Neither owned nor copied.

  fidl::Binding<fuchsia::auth::AuthenticationContextProvider>
      authentication_context_provider_binding_;
  std::string serialized_users_;
  const fuchsia::modular::UsersStorage* users_storage_ = nullptr;

  std::map<UserControllerImpl*, std::unique_ptr<UserControllerImpl>>
      user_controllers_;

  FXL_DISALLOW_COPY_AND_ASSIGN(UserProviderImpl);
};

}  // namespace modular

#endif  // PERIDOT_BIN_BASEMGR_USER_PROVIDER_IMPL_H_
