#include <set>
#include "config.hpp"
#include "../dist/server.hpp"
#include "gtask.hpp"
#include <algorithm>
#include <list>

using namespace std;



int main(int argc,char** argv){
  // Compute the Forest
  list<Semigroup> forest;
  Semigroup O;
  init_full_N(O);
  for(size_t g=0;g<MAX_GENUS;++g){
    auto it=generator_iter<CHILDREN>(O);
    ind_t pos=0;
    it.move_next();
    Semigroup Onext=remove_generator(O,it.get_gen(),pos++);
    while(it.move_next()){
      forest.push_back(remove_generator(O,it.get_gen(),pos++));
    }
    O=Onext;
  }
  // Set tasks
  size_t nb_tasks=forest.size();
  Task* tasks=new Task[nb_tasks];
  size_t ind=0;
  for(auto it=forest.begin();it!=forest.end();++it){
    GTaskInput input;
    input.S=*it;
    tasks[ind].set_input((char*)&input,sizeof(input));
    tasks[ind].set_statut(Task::Unaffected);
    ++ind;
  }

  int l=1;
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if(sockfd<0){
    cerr<<"[Error] Can not open socket"<<endl;
    exit(-1);
  }
  cout<<"*****************"<<endl;
  cout<<"* Wilf - Server *"<<endl;
  cout<<"*****************"<<endl;
  
  cout<<endl;
  cout<<"----------------- [Server info] ----------------"<<endl;
  Server server(MAX_CLIENTS,SERVER_PORT);
  server.treat=&treat;
  cout<<"------------------------------------------------"<<endl;
  cout<<"Max genus =  "<<MAX_GENUS<<endl;
  cout<<"Number of tasks : "<<nb_tasks<<endl;
  server.set_tasks(tasks,nb_tasks);
  do{
    server.listen_for_new_clients();
    server.listen_clients();
    server.treat_messages();
    server.affect_tasks();
    usleep(10000);
  }while(server.has_unfinished_tasks());
  size_t number=0;
  cout<<"***************"<<endl;
  cout<<"*    Bilan    *"<<endl;
  cout<<"***************"<<endl;
  size_t ng[MAX_GENUS+1];
  for(size_t g=0;g<=MAX_GENUS;++g){
    ng[g]=1; //Missing left most of each level
  }  
  for(size_t i=0;i<nb_tasks;++i){
    if(tasks[i].get_statut()==Task::Done){
      GTaskOutput& output=*((GTaskOutput*)tasks[i].get_output());
      for(size_t g=0;g<=MAX_GENUS;++g){
	ng[g]+=output.ng[g];
      }
      /*  if(output.number!=0){
	if(number==0){
	  cout<<"I found "<<output.sample<<endl;
	}
	number+=output.number;
	}*/
    }
  }
  for(size_t g=0;g<=MAX_GENUS;++g){
    cout<<g<<" -> "<<ng[g]<<endl;
  }
  //cout<<"Among a total of "<<number<<endl;
			       
}
