#include "utilities.h"


/* Devuelve 0 si ha llegado al final de la cadena.
/* En token guarda el token encontrado y devuelve la posicion
   donde se ha quedado en la cadena */
int  getToken (char *cadena, char del, int posini, char *token) {
  int pos, i, len;

  len = strlen (cadena);
  i = 0;
  //printf("cadena\n");
  //printf("cadena <%s>\n", cadena);
  //printf("cadena\n");
  bzero (token, sizeof(token));

  pos = posini;
  while ((cadena[pos] != del) && (pos < len)) {
    token[i++] = cadena[pos++];
  }

  token [i] = '\0';

  if (pos == len) {
    return 0;
  }
  return pos+1;
}

char * mayusculas (char *cadena) {
  int i, len;
  char c;
  char *straux;

  len = strlen (cadena);
  straux = malloc (len+1);
  for (i=0; i< len; i++) {
    c = (char) toupper (cadena[i]);
    straux [i] = c;
  }

  return straux;
}

void tableAcceded (char *sql, char *table[MAX_CC]) {
  int i, num;
  char *subsql;
  char *straux;
  char *t1, *t2;

  //JSalas sobra straux = malloc (strlen(sql)+1);

  straux = mayusculas (sql);

  printf ("Consulta en mayusculas : %s\n", straux);

  switch (straux[0]) {
  case 'A':
    // ALTER TABLE
    t1 = strtok (straux, " ");
    t1 = strtok (NULL, " ");
    t1 = strtok (NULL, " ");
    table[0] = malloc (strlen(t1)+1);
    strcpy (table[0], t1);
    break;
    
  case 'C':
    // COMMIT OR CREATE TABLE
    if (straux[1] == 'R') {
      t1 = strtok (straux, " ");
      t1 = strtok (NULL, " ");
      t1 = strtok (NULL, " ");
      table[0] = malloc (strlen(t1)+1);
      strcpy (table[0], t1);
    }
    break;
    
  case 'D':
    // DELETE FROM OR DROP TABLE
    t1 = strtok (straux, " ");
    t1 = strtok (NULL, " ");
    t1 = strtok (NULL, " ");
    table[0] = malloc (strlen(t1)+1);
    strcpy (table[0], t1);
    break;
    
  case 'I':
    // INSERT INTO
    t1 = strtok (straux, " ");
    t1 = strtok (NULL, " ");
    t1 = strtok (NULL, " ");
    table[0] = malloc (strlen(t1)+1);
    strcpy (table[0], t1);
    break;
    
  case 'S': 
    // SET OR SELECT
    if (straux[3] != 'T') {
      num = 0;
      t1 = strstr (straux, " FROM ");
      do {
	t2 = t1+6;
	// Encontrar tablas
	i = 0;
	//i = findTablesOnSelect (t2, table, num);
	num = num + i;
	t1 = strstr (t2, " FROM ");
      }while (strcmp(t1,"") != 0);
    }
    break;
    
  case 'U':
    // UPDATE
    t1 = strtok (straux, " ");
    t1 = strtok (NULL, " ");
    table[0] = malloc (strlen(t1)+1);
    strcpy (table[0], t1);
    break;
  }
}

void typeQuery (char *sql, int *typeQuery, int connection) {
// 0 query
// 1 update
// 2 change database
// 4 begin transaction
// 5 end transaction
// 6 abort transaction
  int i;

  while (sql[i] == ' ') 
    i++;

  if (connection) {
    *typeQuery = 2;
  }
  else {
    switch (sql[i]) {

    case 'A': case 'a':
      // ALTER TABLE
      *typeQuery = 2;
      break;

    case 'B': case 'b':
      // BEGIN
      *typeQuery = 5;
      break;

    case 'C': case 'c':
      // COMMIT OR CREATE TABLE
      if ((sql[i+1] == 'R') || (sql[i+1] == 'r')) {
	*typeQuery = 2;
      }
      else {
	*typeQuery = 7;
      }
      break;

    case 'D': case 'd':
      // DELETE FROM OR DROP TABLE
      if ((sql[i+1] == 'E') || (sql[i+1] == 'e')) {
	*typeQuery = 1;
      }
      else {
	*typeQuery = 2;
      }
      break;

    case 'E': case 'e':
      // END
      *typeQuery = 5;
      break;
      
    case 'I': case 'i':
      // INSERT INTO
      *typeQuery = 1;
      break;

    case 'S': case 's': 
      // SET OR SELECT
      if ((sql[i+3] == 'T')||(sql[i+3] == 't')) {
	*typeQuery = 2;
	 }
      else {
	*typeQuery = 0;
      }
      // 300603
      if ((strstr (sql, "autocommit") != NULL)) {
	printf ("ERROR : pgserver does not accept autocommit = false in this moment\n");
	*typeQuery = 0;
      }
      break;

    case 'R': case 'r':
      // ROLLBACK
      *typeQuery = 6;
      break;

    case 'U': case 'u':
      // UPDATE
      *typeQuery = 1;
      break;
    default :
      // ERROR. The query has less time of procces
      *typeQuery = 0;
    }
  }
}

/**********************************/
/* convert data in buffer to int */
/********************************/

void convertToInt (char *buffer, int size, int *result, int posini) {
  int i = posini;
  int intAux = 0;

  unsigned int aux;

  while (i < size+posini) {
    intAux = (unsigned char) buffer[i] | (intAux << 8);
    i++;
  }
  *result = intAux;
}

/***********************************/
/* convert int and save in Buffer */
/*********************************/

void convertToChar (char *buffer, int size, int posini, int val) {
  int i = size+posini;

  while (i-- > posini) {
    buffer[i] = (unsigned char)(val & 0xff);
    val >>= 8;
  }
}

void itoa (int n, char s[])
{
  int i, sign;

  if ((sign = n) < 0)
    n = -n;
  i = 0;
  do {
    s[i++] = n % 10 + '0';
  } while ((n /= 10) > 0);
  if (sign < 0)
    s[i++] = '-';
  s[i] = '\0';
  reverse(s);
}


void reverse (char s[])
{
  int c, i ,j;

  for (i = 0, j = strlen (s)-1; i<j; i++, j--) {
    c = s[i];
    s[i] = s[j];
    s[j] = c;
  }
}

void copyBuffer (char *destino, char *origen, int size) {
  int i;
  for (i = 0; i <= size; i++) {
    destino[i] = origen[i];
  }
}
