#include "conexion.h"
#include "session_manager.h"
#include "msql_acces.h"

#include <arpa/inet.h>
#include <thread>
#include <unistd.h>

void conexion_client(int client);

conexion::conexion(config_reader &config)
{
  this->config=&config;
  this->data=new msql_acces();
}

int conexion::create_socket(int port)
{
    int s;
    struct sockaddr_in addr;

    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = htonl(INADDR_ANY);

    s = socket(AF_INET, SOCK_STREAM, 0);
    if (s < 0) {
    perror("Unable to create socket");
    exit(EXIT_FAILURE);
    }

    if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
    perror("Unable to bind");
    exit(EXIT_FAILURE);
    }

    if (listen(s, 1) < 0) {
    perror("Unable to listen");
    exit(EXIT_FAILURE);
    }

    return s;
}

void conexion::start_server(){
  int sock;
  string port;
  if(!this->config->get_param("port", port)){
      perror("bad port in config file");
    }
  sock = this->create_socket(atoi(port.data()));

  while(1) {
      struct sockaddr_in addr;
      uint len = sizeof(addr);
      int client = accept(sock, (struct sockaddr*)&addr, &len);
      std::thread t_client(conexion_client , client);
      t_client.detach();
      //cont++;
  }
  close(sock);
}

bool conexion::check_pass(std::string username, std::string passwd){
  return passwd==this->data->get_passwd(username);
}


void conexion_client(int client){
  char     buf [256];

  if (client < 0) {
      perror("Unable to accept");
      exit(EXIT_FAILURE);
  }else{
      session_manager* session = new session_manager(client);
      while(!session->validate_pass());
      session->start_dialog();
      delete (session);
      close(client);
  }
}