// 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/module_resolver/type_inference.h"

#include <string>
#include <vector>

#include <lib/async/cpp/operation.h>
#include <lib/entity/cpp/json.h>
#include <lib/fsl/types/type_converters.h>
#include <src/lib/fxl/macros.h>

namespace modular {

ParameterTypeInferenceHelper::ParameterTypeInferenceHelper(
    fuchsia::modular::EntityResolverPtr entity_resolver)
    : entity_resolver_(std::move(entity_resolver)) {}

ParameterTypeInferenceHelper::~ParameterTypeInferenceHelper() = default;

class ParameterTypeInferenceHelper::GetParameterTypesCall
    : public Operation<std::vector<std::string>> {
 public:
  GetParameterTypesCall(fuchsia::modular::EntityResolver* entity_resolver,
                        const fidl::StringPtr& entity_reference,
                        ResultCall result)
      : Operation("ParameterTypeInferenceHelper::GetParameterTypesCall",
                  std::move(result)),
        entity_resolver_(entity_resolver),
        entity_reference_(entity_reference) {}

  void Run() {
    entity_resolver_->ResolveEntity(entity_reference_, entity_.NewRequest());
    entity_->GetTypes([this](const fidl::VectorPtr<fidl::StringPtr>& types) {
      Done(fidl::To<std::vector<std::string>>(types));
    });
  }

 private:
  fuchsia::modular::EntityResolver* const entity_resolver_;
  fidl::StringPtr const entity_reference_;
  fuchsia::modular::EntityPtr entity_;
};

void ParameterTypeInferenceHelper::GetParameterTypes(
    const fuchsia::modular::ResolverParameterConstraint& parameter_constraint,
    fit::function<void(std::vector<std::string>)> result_callback) {
  if (parameter_constraint.is_entity_type()) {
    result_callback(
        std::vector<std::string>(parameter_constraint.entity_type()->begin(),
                                 parameter_constraint.entity_type()->end()));
  } else if (parameter_constraint.is_json()) {
    std::vector<std::string> types;
    if (!ExtractEntityTypesFromJson(parameter_constraint.json(), &types)) {
      FXL_LOG(WARNING) << "Mal-formed JSON in parameter: "
                       << parameter_constraint.json();
      result_callback({});
    } else {
      result_callback(types);
    }
  } else if (parameter_constraint.is_entity_reference()) {
    operation_collection_.Add(std::make_unique<GetParameterTypesCall>(
        entity_resolver_.get(), parameter_constraint.entity_reference(),
        result_callback));
  } else if (parameter_constraint.is_link_info()) {
    if (parameter_constraint.link_info().allowed_types) {
      std::vector<std::string> types(
          parameter_constraint.link_info()
              .allowed_types->allowed_entity_types->begin(),
          parameter_constraint.link_info()
              .allowed_types->allowed_entity_types->end());
      result_callback(std::move(types));
    } else if (parameter_constraint.link_info().content_snapshot) {
      // TODO(thatguy): See if there's an fuchsia::modular::Entity reference on
      // the fuchsia::modular::Link. If so, get the types from that.  If
      // resolution results in a Module being started, this
      // fuchsia::modular::Link should have its allowed types constrained, since
      // *another* Module is now relying on a small set of types being set.
      // Consider doing this when we move type extraction to the Framework and
      // simplify the Resolver.
      std::string entity_reference;
      if (EntityReferenceFromJson(
              parameter_constraint.link_info().content_snapshot,
              &entity_reference)) {
        operation_collection_.Add(std::make_unique<GetParameterTypesCall>(
            entity_resolver_.get(), entity_reference, result_callback));
      }
    }
  } else {
    FXL_NOTREACHED();
  }
}

}  // namespace modular
