/*
    File:       ModuSessionMysql.cpp
    Contains:
*/

#define __MODU_DEBUG__	1

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "StringParser.h"
#include "QTSSModuleUtils.h"

#include "ModuSessionMysql.h"
#include "mysql.h" 

/* tcpwrapper code */
// #ifndef lint
// static char sccsid[] = "@(#) tcpdmatch.c 1.5 96/02/11 17:01:36";
// #endif

/* System libraries. */

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <syslog.h>
#include <setjmp.h>
#include <string.h>

extern void exit();
extern int optind;
extern char *optarg;

#ifndef	INADDR_NONE
/* XXX should be 0xffffffff */
#define	INADDR_NONE	(-1)
#endif

#ifndef S_ISDIR
#define S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)
#endif

/* Application-specific. */
//#include "tcpd.h"

// static void usage();
// static void tcpdmatch();

ModuSessionMysql::ModuSessionMysql(char* host, char* name, char* user, char* pass, char* port, char* socket){
	// char* directory;
	// char* sessionkey;
	// char* ip;
	// char* dss;
	
	if(socket != NULL){
		if(__MODU_DEBUG__)
			qtss_printf("ModuSessionMysql::ModuSessionMysql using socket %s, overriding host and port\n", socket);
		
		host = "localhost";
		port = "0";
	}
	else{
		if(host == NULL)
			host = "localhost";
		if(port == NULL)
			port="3306";
	}
	
	if(__MODU_DEBUG__){
		if(host != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql host: %s\n", host);
		}
		
		if(socket != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql socket: %s\n", socket);
		}
		
		if(port != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql port: %s\n", port);
		}
		
		if(name != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql name: %s\n", name);
		}
		
		if(user != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql user: %s\n", user);
		}
		
		if(pass != NULL){
			qtss_printf("ModuSessionMysql::ModuSessionMysql pass: %s\n", pass);
		}
	}
	
	mysql_init(&db);
	
	if(mysql_real_connect(&db, host, user, pass, name, atoi(port), socket, 0) == NULL){
		qtss_printf("ModuSessionMysql::ModuSessionMysql successful connect!\n");
	}
}

// Destructor
ModuSessionMysql::~ModuSessionMysql(){
	mysql_close(&db);
}

Bool16 ModuSessionMysql::set(char* d, char* s, char* i, char* dss){
	if(d != NULL){
		directory = d;
	}
	
	if (s != NULL){
		sessionkey = s;
	}
	
	if (i != NULL){
		ip = i;
	}
	
	if (dss != NULL){
		darwin = dss;
	}
	
	return true;
}

Bool16 ModuSessionMysql::check() {
	int ip_len = strlen(ip);
	char ip_str[ip_len*2+1];
	mysql_real_escape_string(&db, ip_str, ip, ip_len);
	
	int sessionkey_len = strlen(sessionkey);
	char sessionkey_str[sessionkey_len*2+1];
	mysql_real_escape_string(&db, sessionkey_str, sessionkey, sessionkey_len);
	
	snprintf(query, 512,
		"SELECT COUNT(*) AS numrows FROM session WHERE IF(IFNULL(user_id, 0), 1, 0) AND client_ip = '%s' AND id = '%s'",
		ip_str, sessionkey_str);
	
	if(__MODU_DEBUG__){
		qtss_printf("ModuSessionMysql::check() query %s\n", query);
	}
	
	mysql_query(&db, query);

	if(rows()){
		if(__MODU_DEBUG__){
			qtss_printf("ModuSessionMysql::check() matching record found %s %s\n", ip, sessionkey);
		}
		
		if(! checkDarwinSession()){
			if (__MODU_DEBUG__){
				qtss_printf("ModuSessionMysql::check() matching shib_darwin not found on initial insert, inserting.\n");
			}
			
			int darwin_len = strlen(darwin);
			char darwin_str[darwin_len*2+1];
			mysql_real_escape_string(&db, darwin_str, darwin, darwin_len);

			snprintf(query, 512, 
				"INSERT INTO darwin (client_ip, darwin_session) VALUES ('%s', '%s')", 
				ip_str, darwin_str);
			
			if(mysql_query(&db, query) != 0){
				if(__MODU_DEBUG__){
					qtss_printf("ModuSessionMysql::check() %s\n", mysql_error(&db));
				}
				return false;
			}
		}
		
		return true;
	}
	else{
		if(__MODU_DEBUG__){
			qtss_printf("ModuSessionMysql::check() no matching record found for %s %s\n", ip, sessionkey);
		}
		return false;
	}
}    

Bool16 ModuSessionMysql::checkDarwinSession() {
	int ip_len = strlen(ip);
	char ip_str[ip_len*2+1];
	mysql_real_escape_string(&db, ip_str, ip, ip_len);
	
	int darwin_len = strlen(darwin);
	char darwin_str[darwin_len*2+1];
	mysql_real_escape_string(&db, darwin_str, darwin, darwin_len);
	
	snprintf(query, 512, 
		"SELECT COUNT(*) AS numrows FROM darwin WHERE client_ip = '%s' and darwin_session = '%s'",
		ip_str, darwin_str);
	
	mysql_query(&db, query);
	
	if(rows()){
		return true;
	}
	
	return false;
}

int ModuSessionMysql::rows(){
	MYSQL_RES* sqlres = mysql_store_result(&db);
	
	if(sqlres == NULL) {
		if(__MODU_DEBUG__){
			qtss_printf("ModuSessionMysql::rows() failed to store result: %s\n", mysql_error(&db));
		}
		return 0;
	}
	
	MYSQL_ROW numrows = mysql_fetch_row(sqlres);
	return atoi(numrows[0]);
}

Bool16 ModuSessionMysql::clearDarwinSessions() {
	snprintf(query, 512, "DELETE FROM darwin");
	
	if(mysql_query(&db, query) != 0) {
		if(__MODU_DEBUG__){
			qtss_printf("ModuSessionMysql::clearDarwinSessions() had some error: %s\n", mysql_error(&db));
		}
		return false;
	}
	else{
		if(__MODU_DEBUG__){
			qtss_printf("ModuSessionMysql::clearDarwinSessions() deleted darwin sessions\n");
		}
		return true;
	}
}


