//
// Created by Dan Crosby on 4/4/20.
//

#ifndef EAGLE0_SHARDOKCOMMAND_HPP
#define EAGLE0_SHARDOKCOMMAND_HPP

#include <memory>
#include <vector>

#include "ActionCost.hpp"
#include "ShardokAction.hpp"
#include "ShardokCTypes.h"
#include "src/main/protobuf/net/eagle0/shardok/api/command_descriptor.pb.h"
#include "src/main/protobuf/net/eagle0/shardok/common/command_type.pb.h"

namespace shardok {

using net::eagle0::shardok::common::CommandType;
using CommandProto = net::eagle0::shardok::api::CommandDescriptor;

//
// Encapsulates a user-issued Command
//
class ShardokCommand : public ShardokAction {
private:
    const PlayerId playerId;

protected:
    explicit ShardokCommand(const PlayerId pid) : playerId(pid){};

public:
    [[nodiscard]] virtual auto GetCommandType() const -> CommandType = 0;

    [[nodiscard]] auto GetPlayerId() const -> PlayerId { return playerId; }

    [[nodiscard]] virtual auto GetCommandProto() const -> CommandProto = 0;

    [[nodiscard]] virtual auto CanBeFollowUp() const -> bool { return true; }
    [[nodiscard]] virtual auto CanDoWithLowMorale() const -> bool { return false; }
    [[nodiscard]] virtual auto CanDoWhileStunned() const -> bool { return false; }
    [[nodiscard]] virtual auto CanDoWithLowVigor() const -> bool { return false; }
    [[nodiscard]] virtual auto CanDoAfterMovingIntoZoc() const -> bool { return false; }
    [[nodiscard]] virtual auto IsRequiredToEndTurn() const -> bool { return false; }
    [[nodiscard]] virtual auto CanUseClientRoll() const -> bool { return false; }
    [[nodiscard]] virtual auto HasOdds() const -> bool { return false; }
    [[nodiscard]] virtual auto GetOddsPercentile() const -> int32_t { return 0; }

    virtual void AddFollowUpCommandTypes(const std::unordered_set<CommandType>& newTypes) {
        throw ShardokInternalErrorException("Can't add follow up commands to this type");
    }
};

using CommandSPtr = shared_ptr<ShardokCommand>;
using CommandList = vector<CommandSPtr>;
using CommandListSPtr = shared_ptr<const CommandList>;

}  // namespace shardok

#endif  // EAGLE0_SHARDOKCOMMAND_HPP
