#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
#include <time.h>
#include "passenger_pool.h"
#include "generator.h"

int main(void)
{
	srand(time(NULL));
    /* Names are assigned from the pools in the header*/
    const char *firstNames[] = FIRST_NAME_POOL;
    const char *lastNames[] = LAST_NAME_POOL;
    const char *seats[] = PLANE_SEATS_POOL;
    const char *months[] = MONTHS_POOL;
    const char *residencies[] = RESIDENCY_POOL;
    const char *emails[] = EMAIL_POOL;
    

    /* Find the counts for the pool sizes */
    int firstNamePoolSize = sizeof(firstNames) / sizeof(char *);
    int lastNamePoolSize = sizeof(lastNames) / sizeof(char *);
    int seatPoolSize = sizeof(seats) / sizeof(char *);
    int monthPoolSize = sizeof(months) / sizeof(char *);
    int residencyPoolSize = sizeof(residencies) / sizeof(char *);
    int emailPoolSize = sizeof(emails) / sizeof(char *);
	
	printf("\nEnter flight id to which flight to generate passengers:");
	int flightId;
	scanf("%d", &flightId);

	printf("\nEnter how many passengers to generate(0-72):");
	int nameCount;
	do
	{
		scanf("%d", &nameCount);
		if(nameCount < 0 && nameCount > 73)
			puts("Invalid number of passengers, Retry:");
			
	}while(nameCount < 0 && nameCount > 73);

	
	users data[SEATS] = {0};
	
	int i, j;
	char seat[4];
	char month[STR_MAX];
	char date[DOB_MAX];
	char mail[STR_MAX];
	char docNum[DOC_MAX];
	char letters[26] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};

	
	for (i = 0; i < nameCount; i++)
	{
		strcpy((data + i)->lName, lastNames[GetRand(0,lastNamePoolSize - 1)]);
		strcpy((data + i)->fName, firstNames[GetRand(0,firstNamePoolSize - 1)]);
		printf("TEST: %s\n", (data + i)->fName);
		do //leitakse random istekoht, kuni funktsioon tagastab et
		{	//kellegil pole seda istkohta otsitakse uus.
			strcpy(seat,seats[GetRand(0,seatPoolSize - 1)]);
		}while (GetUniqueSeat(data, i, seat) > 0);
		
		strcpy((data + i)->seat, seat); //eeldusel et eelmine tsükkel 
		//lõpetab kopeeritakse istekoht struktuurimassiivi
		
		strcpy(month, months[GetRand(0,monthPoolSize - 1)]); 
		GenerateDateOfBirth(month, date); //funktsioonis pannakse numbrid
		strcpy((data + i)->dateOfBirth , date);//ja kuu kokku et saada
										//formaadis sünnikuupäev
		strcpy((data + i)->residency, residencies[GetRand(0,residencyPoolSize - 1)]);
		
		(data + i)->checkedIn = false; //default kõigile
		
		memset(mail, 0, sizeof(mail)); //tühjendab sõne enne uue meili loomist
			
		mail[0] = (data+i)->fName[0];
		mail[strlen(mail)] = '.'; //emaili loomine, null terminaatoreid on
		mail[strlen(mail)] = '\0';//palju et tagada strcati funktsionaalsus
		strcat(mail,(data+i)->lName);
		mail[strlen(mail)] = '\0';
		strcat(mail, emails[GetRand(0, emailPoolSize - 1)]);
		mail[strlen(mail)] = '\0';
		printf("%s\n", mail);
		strcpy((data+i)->email, mail);
		
		for(j = 0; j < 2; j++)
		{
			docNum[j] = letters[GetRand(0,23)];
		}
		for(j = 2; j < 9; j++)	//dokumendi numbri genereerimine
		{
			docNum[j] = '0' + GetRand(0,9) % 10;
		}
		docNum[9] = '\0';
		strcpy((data+i)->documentNum, docNum);
		
		(data + i)->luggageClass = GetRand(0,3);
		
		(data + i)->flight_id = flightId;
	}
	
	puts("Passengers generated, inserting into MySQL database...");
	GenNames(data, nameCount);
	MYSQL* con = connectToMySQLServer();//ühenduse loomine serveriga,
	//tagastus on viit aadressile
	
	for (i = 0; i < nameCount; i++) 
	{
        insertPersonIntoTable(con, data[i]); //sisestatakse ükshaaval iga
    }								//genereeritud isik
    puts("Passengers successfully inserted into MySQL server");
    puts("Show database query? 1-yes 0-no");
    int show;
    scanf("%d", &show);
    
    if (show == 1)
	{
		if (mysql_query(con, "SELECT * FROM Users"))
		{
			finish_with_error(con);
		}
		MYSQL_RES *result = mysql_store_result(con);
		PrintTable(result);

	}
    mysql_close(con);
	

    return EXIT_SUCCESS;
}
void PrintTable(MYSQL_RES *result)
{
	int num_fields = mysql_num_fields(result);

	MYSQL_ROW row;

	while ((row = mysql_fetch_row(result)))
	{
		for(int i = 0; i < num_fields; i++)
		{
			printf("%s ", row[i] ? row[i] : "NULL");
		}

		printf("\n");
	}
}

void insertPersonIntoTable(MYSQL* con, users data) 
{
    char query[1024];
    
    sprintf(query, "INSERT INTO users (documentNum, firstName, " 
		"lastName, dateOfBirth, email, residency, checkedIn, seat,"
		"luggageClass, flight_id) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', %d, %d);"
		,data.documentNum, data.fName, data.lName, data.dateOfBirth, 
		data.email, data.residency, data.checkedIn, data.seat, data.luggageClass,
		data.flight_id);
		
	printf("DEBUG:%s\n\n", query);
		
    if (mysql_query(con, query)) {
        printf("Error inserting Users into MySQL table: %s\n", mysql_error(con));
        exit(EXIT_FAILURE);
    }
}

MYSQL* connectToMySQLServer()
{
    MYSQL* con = mysql_init(NULL);
    if (con == NULL)
	{
		fprintf(stderr, "mysql_init() failed\n");
		exit(1);
	}

	if (mysql_real_connect(con, "127.0.0.1", "root", "Tarkvaraprojekt2023",
          "Lennubroneering", 0, NULL, 0) == NULL)
	{
		finish_with_error(con);
	}
		return con;
}

void finish_with_error(MYSQL *con)
{
  fprintf(stderr, "%s\n", mysql_error(con));
  mysql_close(con);
  exit(EXIT_FAILURE);
}

void GenerateDateOfBirth(char *month, char *dateOB)
{
	
	char dob[20] = {0};
	char temp[15] = {0};
	int date = GetRand(1, 31);
	int year = GetRand(1920,2022);
	
	snprintf(temp, 5, "%d", date);
	strcat(dob, temp);
	dob[strlen(dob)] = '\0';
	dob[strlen(dob)] = '.';
	
	
	strcat(dob, month);
	dob[strlen(dob)] = '\0';
	dob[strlen(dob)] = '.';
	
	snprintf(temp, 5, "%d", year);
	
	strcat(dob, temp);
	dob[strlen(dob)] = '\0';
	
	strcpy(dateOB, dob);
	
	
}
int GetUniqueSeat(users *data, int len, char *seat)
{

	int match = 0; //Otsib kas on kellegil juba sama istekoht
	int i;
	for (i = 0; i < len; i++)
	{
		if (strcmp(seat,(data + i)->seat) == 0)
		{
			match++;
		}
	}
	
	return match;
}



void GenNames(users *data, int num)
{
	FILE *fp = fopen("passengers.txt", "w");
	
	if(fp == NULL)
	{
		puts("Output file did not open!");
		exit(EXIT_FAILURE);
	}
	
	int i;
	
	for (i = 0; i < num; i++)
	{
		fprintf(fp,"%s %s %s %s %s %s %s %d\n",(data + i)->documentNum,
			(data + i)->fName,(data + i)->lName,(data + i)->dateOfBirth,
			(data + i)->email,(data + i)->residency, 
			(data + i)->seat, (data + i)->luggageClass);
	}

	fclose(fp);
}

int GetRand(int min, int max)
{
    return (rand() % (max - min + 1)) + min;
}