// 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_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_
#define PERIDOT_BIN_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_

#include <string>

#include <fuchsia/ledger/internal/cpp/fidl.h>
#include <fuchsia/modular/cpp/fidl.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fidl/cpp/string.h>
#include <lib/fxl/macros.h>

#include "peridot/bin/sessionmgr/entity_provider_runner/entity_provider_runner.h"
#include "peridot/bin/sessionmgr/message_queue/message_queue_manager.h"

namespace modular {

class AgentRunner;

// The parameters of component context that do not vary by instance.
struct ComponentContextInfo {
  MessageQueueManager* const message_queue_manager;
  AgentRunner* const agent_runner;
  fuchsia::ledger::internal::LedgerRepository* const ledger_repository;
  EntityProviderRunner* const entity_provider_runner;
};

// Implements the fuchsia::modular::ComponentContext interface, which is
// provided to modules and agents. The interface is public, because the class
// doesn't contain the Bindings for this interface. TODO(mesch): Move
// bindings into the class.
class ComponentContextImpl : public fuchsia::modular::ComponentContext {
 public:
  // * A component namespace identifies components whose lifetimes are related,
  //   where all of their persisted information will live together; for modules
  //   this is the story id, for agents it is kAgentComponentNamespace, etc.
  // * A component instance ID identifies a particular instance of a component;
  //   for modules, this is the module path in their story. For agents, it is
  //   the agent URL.
  // * A component URL is the origin from which the executable associated with
  //   the component was fetched from.
  explicit ComponentContextImpl(const ComponentContextInfo& info,
                                std::string component_namespace,
                                std::string component_instance_id,
                                std::string component_url);

  ~ComponentContextImpl() override;

  const std::string& component_instance_id() { return component_instance_id_; }

  void Connect(
      fidl::InterfaceRequest<fuchsia::modular::ComponentContext> request);
  fuchsia::modular::ComponentContextPtr NewBinding();

 private:
  // |fuchsia::modular::ComponentContext|
  void GetLedger(
      fidl::InterfaceRequest<fuchsia::ledger::Ledger> request) override;

  // |fuchsia::modular::ComponentContext|
  void ConnectToAgent(std::string url,
                      fidl::InterfaceRequest<fuchsia::sys::ServiceProvider>
                          incoming_services_request,
                      fidl::InterfaceRequest<fuchsia::modular::AgentController>
                          agent_controller_request) override;

  // |fuchsia::modular::ComponentContext|
  void ObtainMessageQueue(
      std::string name,
      fidl::InterfaceRequest<fuchsia::modular::MessageQueue> request) override;

  // |fuchsia::modular::ComponentContext|
  void DeleteMessageQueue(std::string name) override;

  // |fuchsia::modular::ComponentContext|
  void GetMessageSender(
      std::string queue_token,
      fidl::InterfaceRequest<fuchsia::modular::MessageSender> request) override;

  // |fuchsia::modular::ComponentContext|
  void GetEntityResolver(
      fidl::InterfaceRequest<fuchsia::modular::EntityResolver> request)
      override;

  // |fuchsia::modular::ComponentContext|
  void CreateEntityWithData(
      std::vector<fuchsia::modular::TypeToDataEntry> type_to_data,
      CreateEntityWithDataCallback result) override;

  // |fuchsia::modular::ComponentContext|
  void GetPackageName(GetPackageNameCallback result) override;

  MessageQueueManager* const message_queue_manager_;
  AgentRunner* const agent_runner_;
  fuchsia::ledger::internal::LedgerRepository* const ledger_repository_;
  EntityProviderRunner* const entity_provider_runner_;

  const std::string component_namespace_;
  const std::string component_instance_id_;
  const std::string component_url_;

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

  FXL_DISALLOW_COPY_AND_ASSIGN(ComponentContextImpl);
};

}  // namespace modular

#endif  // PERIDOT_BIN_SESSIONMGR_COMPONENT_CONTEXT_IMPL_H_
