//
// Created by Dan Crosby on 3/14/21.
//

#include "CommandFactoriesList.hpp"

#include <memory>

#include "src/main/cpp/net/eagle0/shardok/library/command_factories/BlowBridgeCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/BraveWaterCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/BuildBridgeCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ChallengeDuelCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ChargeCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ControlCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/EvacuatePrisonersCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ExtinguishFireCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/FearCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/FleeCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/FortifyCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/FreezeWaterCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/HideCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/HolyWaveCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/LightningBoltCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/MeteorStartCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/MeteorTargetCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/MoveCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/RaiseDeadCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ReduceCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ReinforceCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/RepairCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/RetreatCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/ScoutCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/StartFireCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/archery_command_factory/ArcheryCommandFactory.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/command_factories/melee_command_factory/MeleeCommandFactory.hpp"

namespace shardok {

auto MakeFactories(const SettingsGetter& settings)
        -> std::vector<std::shared_ptr<const CommandFactory>> {
    // Command factories that produce "must-do" commands like Meteor Target should be first.
    // Ultimately I should probably move that metadata into the CommandFactory and sort it here.

    return {std::make_shared<MeteorTargetCommandFactory>(settings),
            std::make_shared<ControlCommandFactory>(settings),
            std::make_shared<ArcheryCommandFactory>(settings),
            std::make_shared<BlowBridgeCommandFactory>(settings),
            std::make_shared<BraveWaterCommandFactory>(settings),
            std::make_shared<BuildBridgeCommandFactory>(settings),
            std::make_shared<ChallengeDuelCommandFactory>(settings),
            std::make_shared<ChargeCommandFactory>(settings),
            std::make_shared<EvacuatePrisonersCommandFactory>(settings),
            std::make_shared<ExtinguishFireCommandFactory>(settings),
            std::make_shared<FearCommandFactory>(settings),
            std::make_shared<FleeCommandFactory>(settings),
            std::make_shared<FortifyCommandFactory>(settings),
            std::make_shared<FreezeWaterCommandFactory>(settings),
            std::make_shared<HideCommandFactory>(settings),
            std::make_shared<HolyWaveCommandFactory>(settings),
            std::make_shared<LightningBoltCommandFactory>(settings),
            std::make_shared<MeleeCommandFactory>(settings),
            std::make_shared<MeteorStartCommandFactory>(settings),
            std::make_shared<RaiseDeadCommandFactory>(settings),
            std::make_shared<ReduceCommandFactory>(settings),
            std::make_shared<ReinforceCommandFactory>(settings),
            std::make_shared<RepairCommandFactory>(settings),
            std::make_shared<RetreatCommandFactory>(settings),
            std::make_shared<ScoutCommandFactory>(settings),
            std::make_shared<StartFireCommandFactory>(settings),
            std::make_shared<MoveCommandFactory>(settings)};
}

auto CommandFactoriesList::GetFactories() const
        -> std::vector<std::shared_ptr<const CommandFactory>> {
    return factories;
}

CommandFactoriesList::CommandFactoriesList(const SettingsGetter& settings)
    : factories(MakeFactories(settings)) {}
}  // namespace shardok
