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

#include "peridot/bin/context_engine/context_writer_impl.h"

#include <memory>

#include <fuchsia/modular/cpp/fidl.h>
#include <lib/entity/cpp/json.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fit/defer.h>

#include "peridot/bin/context_engine/debug.h"
#include "rapidjson/document.h"

namespace modular {

ContextWriterImpl::ContextWriterImpl(
    const fuchsia::modular::ComponentScope& client_info, ContextRepository* const repository,
    fuchsia::modular::EntityResolver* const entity_resolver,
    fidl::InterfaceRequest<fuchsia::modular::ContextWriter> request)
    : binding_(this, std::move(request)),
      repository_(repository),
      entity_resolver_(entity_resolver),
      weak_factory_(this) {
  FXL_DCHECK(repository != nullptr);

  // Set up a query to the repository to get our parent id.
  if (client_info.is_module_scope()) {
    parent_value_selector_.type = fuchsia::modular::ContextValueType::MODULE;
    parent_value_selector_.meta = fuchsia::modular::ContextMetadata::New();
    parent_value_selector_.meta->story = fuchsia::modular::StoryMetadata::New();
    parent_value_selector_.meta->story->id = client_info.module_scope().story_id;
    parent_value_selector_.meta->mod = fuchsia::modular::ModuleMetadata::New();
    std::vector<std::string> module_path;
    fidl::Clone(client_info.module_scope().module_path, &module_path);
    parent_value_selector_.meta->mod->path = fidl::VectorPtr(std::move(module_path));
  }
}

ContextWriterImpl::~ContextWriterImpl() {}

namespace {

std::vector<std::string> Deprecated_GetTypesFromJsonEntity(const fidl::StringPtr& content) {
  // If the content has the @type attribute, take its contents and populate the
  // fuchsia::modular::EntityMetadata appropriately, overriding whatever is
  // there.
  std::vector<std::string> types;
  if (!ExtractEntityTypesFromJson(content.value_or(""), &types)) {
    FXL_LOG(WARNING) << "Invalid entity metadata in JSON value: " << content;
    return {};
  }

  return types;
}

void MaybeFillEntityTypeMetadata(const std::vector<std::string>& types,
                                 fuchsia::modular::ContextValue& value) {
  if (value.type != fuchsia::modular::ContextValueType::ENTITY)
    return;

  if (!value.meta.entity) {
    value.meta.entity = fuchsia::modular::EntityMetadata::New();
  }
  value.meta.entity->type = fidl::VectorPtr(types);
}

bool MaybeFindParentValueId(ContextRepository* repository,
                            const fuchsia::modular::ContextSelector& selector,
                            ContextRepository::Id* out) {
  // There is technically a race condition here, since on construction, we
  // are given a fuchsia::modular::ComponentScope, which contains some metadata
  // to find a value in the context engine. It is the responsibility of the
  // story_info acquierer to actually create that value, so we query at
  // CreateValue()-time because it makes it less likely to hit the race
  // condition.
  //
  // This is only exercised when a Module publishes context explicitly,
  // something that we plan to disallow once Links speak in Entities, as then
  // Modules that wish to store context can simply write Entities into a new
  // link.
  auto ids = repository->Select(selector);
  if (ids.size() == 1) {
    *out = *ids.begin();
    return true;
  }
  return false;
}

}  // namespace

void ContextWriterImpl::CreateValue(
    fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
    fuchsia::modular::ContextValueType type) {
  ContextRepository::Id parent_id;
  // We ignore the return value - if it returns false |parent_id| will stay
  // default-initialized.
  MaybeFindParentValueId(repository_, parent_value_selector_, &parent_id);
  auto ptr = new ContextValueWriterImpl(this, parent_id, type, std::move(request));
  AddContextValueWriter(ptr);
}

void ContextWriterImpl::AddContextValueWriter(ContextValueWriterImpl* ptr) {
  value_writer_storage_.emplace_back(ptr);
}

void ContextWriterImpl::DestroyContextValueWriter(ContextValueWriterImpl* ptr) {
  auto it = std::remove_if(
      value_writer_storage_.begin(), value_writer_storage_.end(),
      [ptr](const std::unique_ptr<ContextValueWriterImpl>& u_ptr) { return u_ptr.get() == ptr; });
  value_writer_storage_.erase(it, value_writer_storage_.end());
}

void ContextWriterImpl::WriteEntityTopic(std::string topic, fidl::StringPtr value) {
  auto activity = repository_->debug()->GetIdleWaiter()->RegisterOngoingActivity();

  if (!value) {
    // Remove this value.
    auto it = topic_value_ids_.find(topic);
    if (it != topic_value_ids_.end()) {
      repository_->Remove(it->second);
    }
    return;
  }

  GetEntityTypesFromEntityReference(
      value, [this, activity, topic, value](const std::vector<std::string>& types) {
        fuchsia::modular::ContextValue context_value;
        context_value.type = fuchsia::modular::ContextValueType::ENTITY;
        context_value.content = value;
        context_value.meta.entity = fuchsia::modular::EntityMetadata::New();
        context_value.meta.entity->topic = topic;
        context_value.meta.entity->type = fidl::VectorPtr(types);

        auto it = topic_value_ids_.find(topic);
        if (it == topic_value_ids_.end()) {
          ContextRepository::Id parent_id;
          ContextRepository::Id id;
          if (MaybeFindParentValueId(repository_, parent_value_selector_, &parent_id)) {
            id = repository_->Add(parent_id, std::move(context_value));
          } else {
            id = repository_->Add(std::move(context_value));
          }
          topic_value_ids_[topic] = id;
        } else {
          repository_->Update(it->second, std::move(context_value));
        }
      });
}

void ContextWriterImpl::GetEntityTypesFromEntityReference(
    const fidl::StringPtr& reference, fit::function<void(const std::vector<std::string>&)> done) {
  auto activity = repository_->debug()->GetIdleWaiter()->RegisterOngoingActivity();

  // TODO(thatguy): This function could be re-used in multiple places. Move it
  // somewhere other places can reach it.
  std::unique_ptr<fuchsia::modular::EntityPtr> entity =
      std::make_unique<fuchsia::modular::EntityPtr>();
  entity_resolver_->ResolveEntity(reference.value_or(""), entity->NewRequest());

  auto fallback = fit::defer([done = done.share(), reference] {
    // The contents of the fuchsia::modular::Entity value could be a deprecated
    // JSON fuchsia::modular::Entity, not an fuchsia::modular::Entity reference.
    done(Deprecated_GetTypesFromJsonEntity(reference));
  });

  (*entity)->GetTypes(
      [this, activity, id = entities_.GetId(&entity), done = std::move(done),
       fallback = std::move(fallback)](const std::vector<std::string>& types) mutable {
        done(types);
        fallback.cancel();
        entities_.erase(id);
      });

  entities_.emplace(std::move(entity));
}

ContextValueWriterImpl::ContextValueWriterImpl(
    ContextWriterImpl* writer, const ContextRepository::Id& parent_id,
    fuchsia::modular::ContextValueType type,
    fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request)
    : binding_(this, std::move(request)),
      writer_(writer),
      parent_id_(parent_id),
      type_(type),
      value_id_(Future<ContextRepository::Id>::Create("ContextValueWriterImpl.value_id_")),
      weak_factory_(this) {
  binding_.set_error_handler(
      [this](zx_status_t status) { writer_->DestroyContextValueWriter(this); });

  // When |value_id_| completes, we want to remember it so that we know what
  // branch to execute in Set().
  value_id_->WeakConstThen(weak_factory_.GetWeakPtr(),
                           [this](const ContextRepository::Id& id) { have_value_id_ = true; });
}

ContextValueWriterImpl::~ContextValueWriterImpl() {
  // It's possible we haven't actually created a value in |repository_| yet.
  // Either we have, and |value_id_| is complete and this callback will be
  // called synchronously, or we haven't and |value_id_| will go out of scope
  // with *this goes out of scope.
  value_id_->WeakConstThen(weak_factory_.GetWeakPtr(), [this](const ContextRepository::Id& id) {
    // Remove the value.
    writer_->repository()->Remove(id);
  });
}

void ContextValueWriterImpl::CreateChildValue(
    fidl::InterfaceRequest<fuchsia::modular::ContextValueWriter> request,
    fuchsia::modular::ContextValueType type) {
  // We can't create a child value until this value has an ID.
  value_id_->WeakConstThen(
      weak_factory_.GetWeakPtr(),
      [this, request = std::move(request), type](const ContextRepository::Id& value_id) mutable {
        auto ptr = new ContextValueWriterImpl(writer_, value_id, type, std::move(request));
        writer_->AddContextValueWriter(ptr);
      });
}

void ContextValueWriterImpl::Set(fidl::StringPtr content,
                                 fuchsia::modular::ContextMetadataPtr metadata) {
  auto activity = writer_->repository()->debug()->GetIdleWaiter()->RegisterOngoingActivity();

  auto done_getting_types =
      [weak_this = weak_factory_.GetWeakPtr(), activity, content,
       metadata = std::move(metadata)](const std::vector<std::string>& entity_types) mutable {
        if (!weak_this)
          return;

        if (!weak_this->have_value_id_) {
          // We're creating this value for the first time.
          fuchsia::modular::ContextValue value;
          value.type = weak_this->type_;
          value.content = content;
          if (metadata) {
            fidl::Clone(*metadata, &value.meta);
          }
          MaybeFillEntityTypeMetadata(entity_types, value);

          if (weak_this->parent_id_.empty()) {
            weak_this->value_id_->Complete(weak_this->writer_->repository()->Add(std::move(value)));
          } else {
            weak_this->value_id_->Complete(
                weak_this->writer_->repository()->Add(weak_this->parent_id_, std::move(value)));
          }
        } else {
          // We can safely capture everything by reference because we know
          // |weak_this->value_id_| has been completed, which means this
          // callback will be executed immediately.
          weak_this->value_id_->ConstThen([weak_this, &content, &metadata,
                                           &entity_types](const ContextRepository::Id& value_id) {
            if (!weak_this->writer_->repository()->Contains(value_id)) {
              FXL_LOG(FATAL) << "Trying to update non-existent context value (" << value_id
                             << "). New content: " << content << ", new metadata: " << metadata;
            }

            auto value = weak_this->writer_->repository()->Get(value_id);
            if (content) {
              value->content = content;
            }
            if (metadata) {
              fidl::Clone(*metadata, &value->meta);
            }
            MaybeFillEntityTypeMetadata(entity_types, *value);
            weak_this->writer_->repository()->Update(value_id, std::move(*value));
          });
        }
      };

  if (type_ != fuchsia::modular::ContextValueType::ENTITY || !content) {
    // Avoid an extra round-trip to fuchsia::modular::EntityResolver that
    // won't get us anything.
    done_getting_types({});
  } else {
    writer_->GetEntityTypesFromEntityReference(content, std::move(done_getting_types));
  }
}

}  // namespace modular
