#ifndef CONFIG_H_INCLUDED
#define CONFIG_H_INCLUDED
#include <string>
#include <armadillo>
#include <tinyxml2.h>
#include <ostream>
#include <unordered_map>

#include "svm.h"
using namespace std;
using namespace tinyxml2;
extern fstream logging;
namespace syai{
/**
*/
class configuration{
unordered_map<string,string>   parameterset;
public:

string filename;//data file name
string data_type;// type
static const char* dtypename[3];

string simi_dist;
string partition_type;//perceptron, svm

size_t  min_nodes;
size_t  max_level;

double  sigma;

svm_parameter   svmparam;

size_t  numthread;
void parseDoc(const string &docname){
    XMLDocument doc;
    doc.LoadFile(docname.c_str());
    XMLElement  *config = doc.RootElement();
    if(strcasecmp(config->Name(),"config")){
        logging<<"error:\t"<<"config file format invalid.\n";exit(-1);
    }
    XMLElement  *node = config->FirstChildElement("dataset");
    filename = string(node->FirstChildElement("name")->GetText());
    data_type = node->FirstChildElement("type")->GetText();

    node = config->FirstChildElement("algorithm");
    simi_dist = node->FirstChildElement("simi-metrics")->GetText();
    partition_type = node->FirstChildElement("partition-type")->GetText();

    node = config->FirstChildElement("parameter");
    XMLElement *subnode = node->FirstChildElement("tree");
    min_nodes = atoi( subnode->FirstChildElement("min-leaves")->GetText());
    max_level = atoi(subnode->FirstChildElement("max-level")->GetText());
    subnode = node->FirstChildElement("simi-matrix");
    sigma = atof(subnode->FirstChildElement("sigma")->GetText());

    ///classifier
    subnode = node->FirstChildElement("classifier");
    XMLElement *svmnode = subnode->FirstChildElement("svm");
    svmparam.cache_size = atoi(svmnode->FirstChildElement("cache-size")->GetText());
    svmparam.C  = atof(svmnode->FirstChildElement("C")->GetText());
    svmparam.kernel_type    = atoi(svmnode->FirstChildElement("kernel-type")->GetText());
    svmparam.coef0  = atof(svmnode->FirstChildElement("coef0")->GetText());
    svmparam.degree = atoi(svmnode->FirstChildElement("degree")->GetText());
    svmparam.eps    = atof(svmnode->FirstChildElement("eps")->GetText());
    svmparam.gamma  = atof(svmnode->FirstChildElement("gamma")->GetText());
    svmparam.nr_weight = atoi(svmnode->FirstChildElement("nr-weight")->GetText());
    svmparam.nu = atof(svmnode->FirstChildElement("nu")->GetText());
    svmparam.p  = atof(svmnode->FirstChildElement("p")->GetText());
    svmparam.probability    = atoi(svmnode->FirstChildElement("probability")->GetText());
    svmparam.shrinking  = atoi(svmnode->FirstChildElement("shrinking")->GetText());
    svmparam.svm_type   = atoi(svmnode->FirstChildElement("svm-type")->GetText());
    svmparam.weight = nullptr;
    svmparam.weight_label = nullptr;

    numthread = atoi(node->FirstChildElement("thread-number")->GetText());
    return;
}

public:
    configuration(string path="/data/tangcaizhi/plane-tree/config.xml"){//configure file path
        ///default svm setting
        svmparam.svm_type = C_SVC;
        svmparam.kernel_type = LINEAR;
        svmparam.degree = 3;
        svmparam.gamma = 0;	// 1/num_features
        svmparam.coef0 = 0;
        svmparam.nu = 0.5;
        svmparam.cache_size = 1000;
        svmparam.C = 0.01;
        svmparam.eps = 1e-3;
        svmparam.p = 0.1;
        svmparam.shrinking = 1;
        svmparam.probability = 0;
        svmparam.nr_weight = 0;
        svmparam.weight_label = NULL;
        svmparam.weight = NULL;
        parseDoc(path);

    }
    void print_config(ostream&os =std::cout){
    os<<"\n*****************************************************************";
    os<<"\nconifg file:\t\t"<<filename;
    os<<"\ndataset type:\t\t"<<data_type;
    os<<"\nsimilarity metrics is:\t"<<simi_dist;
    os<<"\npartition method:\t"<<partition_type;
    os<<"\nmin nodes:\t\t"<<min_nodes;
    os<<"\nmax level:\t\t"<<max_level;
    os<<"\nsigma:\t\t\t"<<sigma;
    os<<"\nthread numbers:\t\t"<<numthread;
    os<<"\n*****************************************************************";
}
};
const   char*configuration::dtypename[]={"multiclass","multilabel","partiallabel"};
}
#endif // CONFIG_H_INCLUDED
