// Copyright 2018 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/sessionmgr/puppet_master/command_runners/operation_calls/add_mod_call.h"

#include <lib/entity/cpp/json.h>
#include <lib/fidl/cpp/clone.h>
#include <lib/fsl/vmo/strings.h>
#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>

#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/find_modules_call.h"
#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_link_path_for_parameter_name_call.h"
#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/get_types_from_entity_call.h"
#include "peridot/bin/sessionmgr/puppet_master/command_runners/operation_calls/initialize_chain_call.h"
#include "peridot/lib/fidl/clone.h"

namespace modular {

namespace {

class AddModCall : public Operation<fuchsia::modular::ExecuteResult,
                                    fuchsia::modular::ModuleData> {
 public:
  AddModCall(StoryStorage* const story_storage,
             fuchsia::modular::ModuleResolver* const module_resolver,
             fuchsia::modular::EntityResolver* const entity_resolver,
             AddModParams add_mod_params, ResultCall done)
      : Operation("AddModCommandRunner::AddModCall", std::move(done)),
        story_storage_(story_storage),
        module_resolver_(module_resolver),
        entity_resolver_(entity_resolver),
        add_mod_params_(std::move(add_mod_params)) {}

 private:
  void Run() override {
    FlowToken flow{this, &out_result_, &out_module_data_};

    // Success status by default, it will be update it if an error state is
    // found.
    out_result_.status = fuchsia::modular::ExecuteStatus::OK;

    // If we have an action, we use the module resolver to type-check and
    // resolve the (action, parameter) and the supplied optional handler to a
    // module. If the module resolver doesn't recognize a supplied handler, we
    // forgivingly execute the handler anyway.
    if (!add_mod_params_.intent.action.is_null()) {
      AddFindModulesOperation(
          &operation_queue_, module_resolver_, entity_resolver_,
          CloneOptional(add_mod_params_.intent),
          add_mod_params_.parent_mod_path,
          [this, flow](fuchsia::modular::ExecuteResult result,
                       fuchsia::modular::FindModulesResponse response) {
            if (result.status != fuchsia::modular::ExecuteStatus::OK) {
              out_result_ = std::move(result);
              return;
              // Operation finishes since |flow| goes out of scope.
            }

            // NOTE: leave this as a switch case and omit the default case; the
            // compiler will make sure we're handling all error cases.
            switch (response.status) {
              case fuchsia::modular::FindModulesStatus::SUCCESS: {
                if (response.results.empty()) {
                  out_result_.status =
                      fuchsia::modular::ExecuteStatus::NO_MODULES_FOUND;
                  out_result_.error_message =
                      "Resolution of intent gave zero results.";
                  return;
                  // Operation finishes since |flow| goes out of scope.
                }

                candidate_module_ = std::move(response.results.at(0));
              } break;

              case fuchsia::modular::FindModulesStatus::UNKNOWN_HANDLER: {
                candidate_module_.module_id = add_mod_params_.intent.handler;
              } break;
            }

            CreateLinks(flow);
          });
    } else {
      // We arrive here if the Intent has a handler, but no action.
      FXL_DCHECK(!add_mod_params_.intent.handler.is_null())
          << "Cannot start a module without an action or a handler";
      candidate_module_.module_id = add_mod_params_.intent.handler;

      CreateLinks(flow);
    }
  }

  // Create module parameters info and create links.
  void CreateLinks(FlowToken flow) {
    CreateModuleParameterMapInfo(flow, [this, flow] {
      if (out_result_.status != fuchsia::modular::ExecuteStatus::OK) {
        return;
        // Operation finishes since |flow| goes out of scope.
      }
      auto full_module_path = add_mod_params_.parent_mod_path;
      full_module_path.push_back(add_mod_params_.mod_name);
      AddInitializeChainOperation(
          &operation_queue_, story_storage_, std::move(full_module_path),
          std::move(parameter_info_),
          [this, flow](fuchsia::modular::ExecuteResult result,
                       fuchsia::modular::ModuleParameterMapPtr map) {
            if (result.status != fuchsia::modular::ExecuteStatus::OK) {
              out_result_ = std::move(result);
              return;
              // Operation finishes since |flow| goes out of scope.
            }
            WriteModuleData(flow, std::move(map));
          });
    });
  }

  // On success, populates |parameter_info_|. On failure, |out_result_| contains
  // error reason. Calls |done()| on completion in either case.
  void CreateModuleParameterMapInfo(FlowToken flow,
                                    fit::function<void()> done) {
    parameter_info_ = fuchsia::modular::CreateModuleParameterMapInfo::New();

    std::vector<FuturePtr<fuchsia::modular::CreateModuleParameterMapEntry>>
        did_get_entries;
    did_get_entries.reserve(add_mod_params_.intent.parameters->size());

    for (auto& param : *add_mod_params_.intent.parameters) {
      fuchsia::modular::CreateModuleParameterMapEntry entry;
      entry.key = param.name;

      switch (param.data.Which()) {
        case fuchsia::modular::IntentParameterData::Tag::kEntityReference: {
          fuchsia::modular::CreateLinkInfo create_link;
          fsl::SizedVmo vmo;
          FXL_CHECK(fsl::VmoFromString(
              EntityReferenceToJson(param.data.entity_reference()), &vmo));
          create_link.initial_data = std::move(vmo).ToTransport();
          entry.value.set_create_link(std::move(create_link));
          break;
        }
        case fuchsia::modular::IntentParameterData::Tag::kEntityType: {
          // Create a link, but don't populate it. This is useful in the event
          // that the link is used as an 'output' link. Setting a valid JSON
          // value for null in the vmo.
          fsl::SizedVmo vmo;
          FXL_CHECK(fsl::VmoFromString("null", &vmo));
          fuchsia::modular::CreateLinkInfo create_link;
          create_link.initial_data = std::move(vmo).ToTransport();
          entry.value.set_create_link(std::move(create_link));
          break;
        }
        case fuchsia::modular::IntentParameterData::Tag::kJson: {
          fuchsia::modular::CreateLinkInfo create_link;
          param.data.json().Clone(&create_link.initial_data);
          entry.value.set_create_link(std::move(create_link));
          break;
        }
        case fuchsia::modular::IntentParameterData::Tag::Invalid: {
          out_result_.status = fuchsia::modular::ExecuteStatus::INVALID_COMMAND;
          out_result_.error_message =
              fxl::StringPrintf("Invalid data for parameter with name: %s",
                                param.name.get().c_str());
          done();
          return;
        }
      }

      auto did_create_entry =
          Future<fuchsia::modular::CreateModuleParameterMapEntry>::
              CreateCompleted(
                  "AddModCommandRunner::FindModulesCall.did_create_entry",
                  std::move(entry));
      did_get_entries.emplace_back(std::move(did_create_entry));
    }

    Wait("AddModCommandRunner::AddModCall::Wait", did_get_entries)
        ->Then([this, done = std::move(done), flow](
                   std::vector<fuchsia::modular::CreateModuleParameterMapEntry>
                       entries) {
          parameter_info_->property_info.reset(std::move(entries));
          done();
        });
  }

  // Write module data
  void WriteModuleData(FlowToken flow,
                       fuchsia::modular::ModuleParameterMapPtr map) {
    fidl::Clone(*map, &out_module_data_.parameter_map);
    out_module_data_.module_url = candidate_module_.module_id;
    out_module_data_.module_path = add_mod_params_.parent_mod_path;
    out_module_data_.module_path.push_back(add_mod_params_.mod_name);
    out_module_data_.module_source = add_mod_params_.module_source;
    out_module_data_.module_deleted = false;
    fidl::Clone(add_mod_params_.surface_relation,
                &out_module_data_.surface_relation);
    out_module_data_.is_embedded = add_mod_params_.is_embedded;
    out_module_data_.intent = std::make_unique<fuchsia::modular::Intent>(
        std::move(add_mod_params_.intent));

    // Operation stays alive until flow goes out of scope.
    fuchsia::modular::ModuleData module_data;
    out_module_data_.Clone(&module_data);
    story_storage_->WriteModuleData(std::move(module_data))->Then([flow] {
    });
  }

  StoryStorage* const story_storage_;                        // Not owned.
  fuchsia::modular::ModuleResolver* const module_resolver_;  // Not owned.
  fuchsia::modular::EntityResolver* const entity_resolver_;  // Not owned.
  modular::AddModParams add_mod_params_;
  fuchsia::modular::FindModulesResult candidate_module_;
  fuchsia::modular::CreateModuleParameterMapInfoPtr parameter_info_;
  fuchsia::modular::ModuleData out_module_data_;
  fuchsia::modular::ExecuteResult out_result_;
  // Used when creating the map info to execute an operation as soon as it
  // arrives.
  OperationCollection operations_;
  // Used to enqueue sub-operations that should be executed sequentially.
  OperationQueue operation_queue_;
};

}  // namespace

void AddAddModOperation(OperationContainer* const container,
                        StoryStorage* const story_storage,
                        fuchsia::modular::ModuleResolver* const module_resolver,
                        fuchsia::modular::EntityResolver* const entity_resolver,
                        AddModParams add_mod_params,
                        fit::function<void(fuchsia::modular::ExecuteResult,
                                           fuchsia::modular::ModuleData)>
                            done) {
  container->Add(std::make_unique<AddModCall>(
      story_storage, module_resolver, entity_resolver,
      std::move(add_mod_params), std::move(done)));
}

}  // namespace modular
