// 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/suggestion_engine/ranking_features/mod_pair_ranking_feature.h"

#include <lib/context/cpp/context_helper.h>
#include <lib/fxl/logging.h>

#include "rapidjson/document.h"
#include "rapidjson/schema.h"

namespace modular {

namespace {
// Sample map using data collected between Feb 6-20, 2018
constexpr char kDataFilePath[] = "/pkg/data/ranking_data/mod_pairs.json";
}  // namespace

ModPairRankingFeature::ModPairRankingFeature(const bool init_data) {
  if (init_data) {
    LoadDataFromFile(kDataFilePath);
  }
}

ModPairRankingFeature::~ModPairRankingFeature() = default;

void ModPairRankingFeature::LoadDataFromFile(const std::string& filepath) {
  auto maybe_result = FetchJsonObject(filepath);
  if (!maybe_result.has_value()) {
    FXL_LOG(WARNING) << "Failed to fetch mod pairs ranking feature data.";
    return;
  }
  auto& result = maybe_result.value();
  module_pairs_.clear();
  for (rapidjson::Value::ConstMemberIterator iter = result.MemberBegin();
       iter != result.MemberEnd(); ++iter) {
    const std::string existing_mod_url = iter->name.GetString();
    rapidjson::Value& other_mods = result[existing_mod_url.c_str()];
    for (rapidjson::Value::ConstMemberIterator iter2 = other_mods.MemberBegin();
         iter2 != other_mods.MemberEnd(); ++iter2) {
      const std::string added_mod_url = iter2->name.GetString();
      module_pairs_[existing_mod_url][added_mod_url] = iter2->value.GetDouble();
    }
  }
}

double ModPairRankingFeature::ComputeFeatureInternal(
    const fuchsia::modular::UserInput& query,
    const RankedSuggestion& suggestion) {
  double prob = 0.0;

  for (auto& command : suggestion.prototype->proposal.on_selected) {
    fidl::StringPtr module_url;
    switch (command.Which()) {
      case fuchsia::modular::StoryCommand::Tag::kAddMod: {
        module_url = command.add_mod().intent.handler;
        break;
      }
      case fuchsia::modular::StoryCommand::Tag::kSetKindOfProtoStoryOption:
      case fuchsia::modular::StoryCommand::Tag::kSetFocusState:
      case fuchsia::modular::StoryCommand::Tag::kFocusMod:
      case fuchsia::modular::StoryCommand::Tag::kSetLinkValue:
      case fuchsia::modular::StoryCommand::Tag::kRemoveMod:
      case fuchsia::modular::StoryCommand::Tag::Invalid:
        continue;
    }
    if (module_url.is_null() || module_url->empty()) {
      continue;
    }
    // Currently computing: max{P(m|mi) for mi in modules_in_source_story}
    // TODO(miguelfrde): compute P(module_url | modules in source story)
    for (auto& context_value : *ContextValues()) {
      const std::string existing_mod_url = context_value.meta.mod->url;
      if (module_pairs_.count(existing_mod_url) &&
          module_pairs_[existing_mod_url].count(module_url)) {
        prob = std::max(prob, module_pairs_[existing_mod_url][module_url]);
      }
    }
  }
  return prob;
}

fuchsia::modular::ContextSelectorPtr
ModPairRankingFeature::CreateContextSelectorInternal() {
  // Get modules in the currently focused story.
  auto selector = fuchsia::modular::ContextSelector::New();
  selector->type = fuchsia::modular::ContextValueType::MODULE;
  selector->meta = fuchsia::modular::ContextMetadata::New();
  selector->meta->story = fuchsia::modular::StoryMetadata::New();
  selector->meta->story->focused = fuchsia::modular::FocusedState::New();
  selector->meta->story->focused->state =
      fuchsia::modular::FocusedStateState::FOCUSED;
  return selector;
}

}  // namespace modular
