//
// Created by Dan Crosby on 3/23/20.
//

#include "HeroFilter.hpp"

#include "src/main/cpp/net/eagle0/shardok/library/map/Coordinates.hpp"

namespace shardok {

using net::eagle0::shardok::api::HeroView;

[[nodiscard]] net::eagle0::shardok::api::HeroView HeroFilteredForPlayer(
        const SettingsGetter &settings,
        const net::eagle0::shardok::storage::fb::Hero &hero,
        const double opponentKnowledge,
        const bool belongsToAsker) {
    HeroView filtered{};

    if (belongsToAsker ||
        opponentKnowledge >= settings.Backing().minimum_knowledge_for_profession()) {
        net::eagle0::shardok::api::HeroView_ProfessionSpecificInfo *professionInfo =
                filtered.mutable_profession_info();
        professionInfo->set_profession(
                static_cast<
                        ::net::eagle0::shardok::api::HeroView_ProfessionSpecificInfo_Profession>(
                        hero.profession_info().profession()));
        professionInfo->set_meteor_cast_state(
                static_cast<::net::eagle0::shardok::api::
                                    HeroView_ProfessionSpecificInfo_MultiroundMagicState>(
                        hero.profession_info().meteor_cast_state()));

        if (belongsToAsker && hero.profession_info().cast_target().row() != -1) {
            *professionInfo->mutable_cast_target() =
                    ToCoordsProto(hero.profession_info().cast_target());
        }
    }

    if (belongsToAsker || opponentKnowledge >= settings.Backing().minimum_knowledge_for_name()) {
        filtered.mutable_eagle_hero_id()->set_value(hero.eagle_hero_id());
        filtered.mutable_is_vip()->set_value(hero.is_vip());
    }

    if (hero.control_info().controlled_unit_id() != -1) {
        filtered.mutable_control_info()->set_controlled_unit_id(
                hero.control_info().controlled_unit_id());

        if (belongsToAsker ||
            opponentKnowledge >= settings.Backing().minimum_knowledge_for_battalion_stats()) {
            filtered.mutable_control_info()->set_controlled_this_round(
                    hero.control_info().controlled_this_round());
        }
    }

    if (belongsToAsker ||
        opponentKnowledge >= settings.Backing().minimum_knowledge_for_hero_stats()) {
        HeroView::Stats *stats = filtered.mutable_stats();
        stats->set_strength(hero.strength());
        stats->set_agility(hero.agility());
        stats->set_constitution(hero.constitution());
        stats->set_charisma(hero.charisma());
        stats->set_wisdom(hero.wisdom());
        stats->set_integrity(hero.integrity());
        stats->set_ambition(hero.ambition());
        stats->set_gregariousness(hero.gregariousness());
        stats->set_bravery(hero.bravery());
        stats->set_vigor(hero.vigor());

        if (belongsToAsker) {
            stats->set_starting_vigor(hero.vigor());

            HeroView::StatXp *statXp = filtered.mutable_stat_xp();
            statXp->set_strength_xp(hero.strength_xp());
            statXp->set_agility_xp(hero.agility_xp());
            statXp->set_charisma_xp(hero.charisma_xp());
            statXp->set_wisdom_xp(hero.wisdom_xp());
        }
    }

    return filtered;
}

}  // namespace shardok