#include "basesolver.hpp"
#include <deque>

struct kissat;
struct cvec;

class basekissat : public basesolver {
public:
    void terminate();
    void add(int l);
    int  solve();
    int  val(int l);
    void configure(const char* name, int id);

    int  get_conflicts();
    void parse_from_CNF(char* filename);
    void parse_from_PAR(preprocess *pre);
    void get_model(vec<int> &model);
    void exp_clause(void *cl, int lbd);
    bool imp_clause(clause_store *cls, void *cl);
    void export_clauses_to(vec<clause_store *> &clauses);
    void import_clauses_from(vec<clause_store *> &clauses);
    void broaden_export_limit();
    void restrict_export_limit();
    double get_waiting_time();

    basekissat(int id, light *light);
    ~basekissat();
    int x1 = 0, x2 = 0;
    double waiting_time = 0;
    kissat* solver;
    int good_clause_lbd = 0;
    
    void select_clauses();
    int get_period() {
        boost::mutex::scoped_lock lock(mtx);
        return period;
    };
    void inc_period() {
        boost::mutex::scoped_lock lock(mtx);
        period++;
        if (period % 100 == 0) printf("c %d reach period %d\n", id, period);
        cond.notify_all();
    };

    void set_winner_period() {
        boost::mutex::scoped_lock lock(mtx);
        winner_period = period;
        cond.notify_all();
    }

    void dps_terminate() {
        {
            boost::mutex::scoped_lock lock(mtx);
            terminated = 1;
            cond.notify_all();
            // printf("c thread %d terminated\n", id);
        }
        terminate();
    }

    friend int cbkImportClause(void *, int *, cvec *);
    friend int cbkExportClause(void *, int *, cvec *);
    friend int cbkWaitSharing(void *);
    friend void cbkFreeClause(void *);
    std::ofstream outimport;
    std::ofstream outexport;
    std::ofstream outfree;
};