// 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_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_
#define PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_

#include <map>
#include <string>

#include <fuchsia/modular/cpp/fidl.h>
#include <lib/async/cpp/future.h>
#include <src/lib/fxl/memory/weak_ptr.h>

#include "peridot/bin/context_engine/context_repository.h"
#include "peridot/lib/bound_set/bound_set.h"

namespace modular {

class ContextRepository;
class ContextValueWriterImpl;
class EntityResolver;

class ContextWriterImpl : fuchsia::modular::ContextWriter {
 public:
  ContextWriterImpl(
      const fuchsia::modular::ComponentScope& client_info,
      ContextRepository* repository,
      fuchsia::modular::EntityResolver* entity_resolver,
      fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request);
  ~ContextWriterImpl() override;

  // Takes ownership of |ptr|. Used by ContextWriterImpl and
  // ContextValueWriterImpl.
  void AddContextValueWriter(ContextValueWriterImpl* ptr);

  // Destroys |ptr| and removes it from |value_writer_storage_|. Used by
  // ContextValueWriterImpl on connection error.
  void DestroyContextValueWriter(ContextValueWriterImpl* ptr);

  // Used by ContextValueWriterImpl.
  ContextRepository* repository() const { return repository_; }

  // Used by ContextValueWriterImpl.
  void GetEntityTypesFromEntityReference(
      const fidl::StringPtr& reference,
      fit::function<void(const std::vector<std::string>&)> done);

 private:
  // |fuchsia::modular::ContextWriter|
  void CreateValue(
      fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
      fuchsia::modular::ContextValueType type) override;

  // |fuchsia::modular::ContextWriter|
  void WriteEntityTopic(std::string topic, fidl::StringPtr value) override;

  fidl::Binding<fuchsia::modular::ContextWriter> binding_;

  fuchsia::modular::ContextSelector parent_value_selector_;
  ContextRepository* const repository_;
  fuchsia::modular::EntityResolver* const entity_resolver_;

  // Supports WriteEntityTopic.
  std::map<fidl::StringPtr, ContextRepository::Id> topic_value_ids_;

  // Supports CreateValue().
  std::vector<std::unique_ptr<ContextValueWriterImpl>> value_writer_storage_;

  // Supports GetEntityTypesFromEntityReference
  //
  // TODO(rosswang): consider adding removal capability to |InterfacePtrSet|
  // instead.
  BoundPtrSet<fuchsia::modular::Entity> entities_;

  fxl::WeakPtrFactory<ContextWriterImpl> weak_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ContextWriterImpl);
};

class ContextValueWriterImpl : fuchsia::modular::ContextValueWriter {
 public:
  // Binds |request| to |this|, and configures it to call
  // |writer->DestroyContextValueWriter(this)| when a connection error occurs.
  // Assumes that |writer->AddContextValueWriter(this)| has already been
  // called. If |parent_id| is set, the new value will have |parent_id| as its
  // parent value.
  //
  // Does not take ownership of |writer|.
  ContextValueWriterImpl(
      ContextWriterImpl* writer, const ContextRepository::Id& parent_id,
      fuchsia::modular::ContextValueType type,
      fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request);
  ~ContextValueWriterImpl() override;

 private:
  // |fuchsia::modular::ContextValueWriter|
  void CreateChildValue(
      fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
      fuchsia::modular::ContextValueType type) override;

  // |fuchsia::modular::ContextValueWriter|
  void Set(fidl::StringPtr content,
           fuchsia::modular::ContextMetadataPtr metadata) override;

  fidl::Binding<fuchsia::modular::ContextValueWriter> binding_;

  ContextWriterImpl* const writer_;
  const ContextRepository::Id parent_id_;
  fuchsia::modular::ContextValueType type_;
  FuturePtr<ContextRepository::Id> value_id_;
  bool have_value_id_{};

  fxl::WeakPtrFactory<ContextValueWriterImpl> weak_factory_;

  FXL_DISALLOW_COPY_AND_ASSIGN(ContextValueWriterImpl);
};

}  // namespace modular

#endif  // PERIDOT_BIN_CONTEXT_ENGINE_CONTEXT_WRITER_IMPL_H_
