/*Copyright (C) 2010-2023 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DEF_GAME_METADATA
#define DEF_GAME_METADATA

#include "Fight/FightRules.hpp"
#include "Fight/FightState.hpp"
#include "Network/Serialization/PeerData.hpp" ///< PeerData and PeerRole
#include <cstdint>
#include <vector>
#include <list>
#include <string>

/// Tools to serialize and read game metadata information
namespace GameMetadataTools
{
    void writeRules(const FightRules &rules, std::list<std::uint8_t> &dst);
    bool readRules(std::list<std::uint8_t> &bytes, FightRules &dst);

    bool writeFightState(const FightState &state, std::list<std::uint8_t> &dst);
    bool readFightState(std::list<std::uint8_t> &bytes, FightState &dst);
}

class GameMetadata
{
    public:
        GameMetadata();
        GameMetadata(const std::string &arena, const FightRules &rules,
                     const std::vector<PeerData> &players,
                     const std::vector<PeerData> &spectators);

        /// Information targeted at the message receiver
        /// to inform it of its place in the peer list
        void setPeerRole(const PeerRole &role);

        /// Set the fight state, switches from in lobby to in game
        void setFightState(const FightState &state);

        /// Read/write from buffer
        bool readFromBuffer(std::list<std::uint8_t> &bytes);
        bool writeToBuffer(std::list<std::uint8_t> &dst) const;

        //Peers and players data: list of connected players and spectators
        const std::vector<PeerData> &getPlayers() const;
        const std::vector<PeerData> &getSpectators() const;
        const PeerRole &getPeerRole() const;

        //Arena, rules, current state (in lobby or state details)
        const std::string &getArena() const;
        const FightRules &getFightRules() const;
        const FightState &getFightState() const;
        bool inServerLobby() const;

    private:
        std::string m_arena;
        FightRules m_rules;

        /// A fight is ongoing, stores the state of the game
        FightState m_state;

        /// Whether the server is in lobby mode, i.e., no fight is started,
        /// players are free to move around
        bool m_serverLobby;

        /// Peer data for each player
        std::vector<PeerData> m_players;

        /// Peer data for each spectator
        std::vector<PeerData> m_spectators;

        /// Role of the client receiving this message from the server
        /// (player? spectator?)
        PeerRole m_peerRole;
};

#endif
