#ifndef FACTBASE_HPP
#define FACTBASE_HPP

#include <cstdint>
#include <functional>
#include <vector>

#include <boost/archive/tmpdir.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>

#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <boost/serialization/string.hpp>

#include <boost/serialization/is_bitwise_serializable.hpp>

#include "quality.h"
#include "topology.h"

class NetworkState;

/** Factbase class
 * @brief Contains known facts in a NetworkState.
 * @details Contains known facts that are completely true in the
 *          NetworkState such as Qualities and Topologies.
 */
class Factbase {
    static int current_id;
    //int current_id;
    friend std::ostream & operator << (std::ostream &os, const Factbase &fb);
    friend class boost::serialization::access;
    int id;

    int qsize;
    int tsize;

    std::vector<Quality> qualities;
    std::vector<Topology> topologies;

    Factbase(std::vector<Quality> q, std::vector<Topology> t);

    friend class NetworkState;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int /* file_version */){
        //ar & qualities & topologies & id;
        ar & current_id & id & qsize & tsize & qualities & topologies;
        //ar & qualities;
        //ar & topologies;
    }

  public:

    Factbase();

    std::tuple<std::vector<Quality>, std::vector<Topology>> get_facts_tuple() const;

    bool find_quality(Quality &q) const;
    bool find_topology(Topology &t) const;

    std::vector<Quality>::iterator get_quality(Quality &q);
    std::vector<Topology>::iterator get_topology(Topology &t);

    void add_quality(Quality &q);
    void add_topology(Topology &t);

    void delete_quality(Quality &q);
    void delete_topology(Topology &t);

    void print() const;
    void set_id();
    void force_set_id(int i);
    void force_set_id(size_t i);
    void reset_curr_id();
    void reset_curr_id(int i);
    int get_id() const;
    size_t hash(Keyvalue &factlist);
    int get_size();
};

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Factbase)

#endif
