/***************************************************************************
  
  options.h
  
  (c) Benoît Minisini <benoit.minisini@gambas-basic.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  MA 02110-1301, USA.
  
***************************************************************************/

#define __OPTIONS_H

typedef
	struct {
		const char *key;
		int cst;
		int type;
		}
	DB_MYSQL_OPTION;

static MYSQL *_options_conn;

#ifndef LIBMYSQL_VERSION_ID
#define LIBMYSQL_VERSION_ID MYSQL_VERSION_ID
#endif

static DB_MYSQL_OPTION _options[] = {
#if LIBMYSQL_VERSION_ID >= 50000
	{ "INIT_COMMAND", MYSQL_INIT_COMMAND, GB_T_STRING },
	{ "COMPRESS", MYSQL_OPT_COMPRESS, GB_T_BOOLEAN },
	{ "CONNECT_TIMEOUT ", MYSQL_OPT_CONNECT_TIMEOUT , GB_T_INTEGER},
	{ "LOCAL_INFILE", MYSQL_OPT_LOCAL_INFILE, GB_T_BOOLEAN},
	{ "PROTOCOL", MYSQL_OPT_PROTOCOL, GB_T_STRING},
	{ "READ_TIMEOUT", MYSQL_OPT_READ_TIMEOUT, GB_T_INTEGER},
	{ "WRITE_TIMEOUT", MYSQL_OPT_WRITE_TIMEOUT, GB_T_INTEGER},
	{ "READ_DEFAULT_FILE", MYSQL_READ_DEFAULT_FILE, GB_T_STRING},
	{ "READ_DEFAULT_GROUP", MYSQL_READ_DEFAULT_GROUP, GB_T_STRING},
	{ "REPORT_DATA_TRUNCATION", MYSQL_REPORT_DATA_TRUNCATION, GB_T_BOOLEAN},
	{ "SET_CHARSET_DIR", MYSQL_SET_CHARSET_DIR, GB_T_STRING},
	{ "SET_CHARSET_NAME", MYSQL_SET_CHARSET_NAME, GB_T_STRING},
#endif

#if LIBMYSQL_VERSION_ID >= 50200
	{ "DEFAULT_AUTH", MYSQL_DEFAULT_AUTH, GB_T_STRING },
	{ "ENABLE_CLEARTEXT_PLUGIN", MYSQL_ENABLE_CLEARTEXT_PLUGIN, GB_T_BOOLEAN },
	{ "PLUGIN_DIR", MYSQL_PLUGIN_DIR, GB_T_STRING},
#endif

#if LIBMYSQL_VERSION_ID >= 50626
	{ "BIND", MYSQL_OPT_BIND, GB_T_STRING },
	{ "CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, GB_T_BOOLEAN },
	{ "SSL_CA", MYSQL_OPT_SSL_CA, GB_T_STRING},
	{ "SSL_CAPATH", MYSQL_OPT_SSL_CAPATH, GB_T_STRING},
	{ "SSL_CERT", MYSQL_OPT_SSL_CERT, GB_T_STRING},
	{ "SSL_CIPHER", MYSQL_OPT_SSL_CIPHER, GB_T_STRING},
	{ "SSL_CRL", MYSQL_OPT_SSL_CRL, GB_T_STRING},
	{ "SSL_CRLPATH", MYSQL_OPT_SSL_CRLPATH, GB_T_STRING},
	{ "SSL_KEY", MYSQL_OPT_SSL_KEY, GB_T_STRING},
	{ "SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, GB_T_STRING},
#endif	

#if LIBMYSQL_VERSION_ID >= 50700
	{ "MAX_ALLOWED_PACKET", MYSQL_OPT_MAX_ALLOWED_PACKET, GB_T_INTEGER},
	{ "NET_BUFFER_LENGTH", MYSQL_OPT_NET_BUFFER_LENGTH, GB_T_INTEGER},
	{ "TLS_VERSION", MYSQL_OPT_TLS_VERSION, GB_T_STRING},
#endif

#if HAVE_MYSQL_SECURE_AUTH
	{ "SECURE_AUTH", MYSQL_SECURE_AUTH, GB_T_BOOLEAN},
#endif
#if HAVE_MYSQL_OPT_COMPRESSION_ALGORITHMS
	{ "COMPRESSION_ALGORITHMS", MYSQL_OPT_COMPRESSION_ALGORITHMS, GB_T_STRING},
#endif
#if HAVE_MYSQL_OPT_GET_SERVER_PUBLIC_KEY
	{ "GET_SERVER_PUBLIC_KEY", MYSQL_OPT_GET_SERVER_PUBLIC_KEY, GB_T_BOOLEAN},
#endif
#if HAVE_MYSQL_OPT_LOAD_DATA_LOCAL_DIR	
	{ "LOAD_DATA_LOCAL_DIR", MYSQL_OPT_LOAD_DATA_LOCAL_DIR, GB_T_STRING},
#endif
#if HAVE_MYSQL_OPT_RECONNECT
	{ "RECONNECT", MYSQL_OPT_RECONNECT, GB_T_BOOLEAN},
#endif
#if HAVE_MYSQL_OPT_RETRY_COUNT
	{ "RETRY_COUNT ", MYSQL_OPT_RETRY_COUNT , GB_T_INTEGER},
#endif
#if HAVE_MYSQL_OPT_SSL_FIPS_MODE
	{ "SSL_FIPS_MODE", MYSQL_OPT_SSL_FIPS_MODE, GB_T_INTEGER},
#endif
#if HAVE_MYSQL_OPT_SSL_MODE	
	{ "SSL_MODE", MYSQL_OPT_SSL_MODE, GB_T_STRING},
#endif
#if HAVE_MYSQL_OPT_SSL_VERIFY_SERVER_CERT
	{ "SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, GB_T_BOOLEAN},
#endif
#if HAVE_MYSQL_OPT_TLS_CIPHERSUITES
	{ "TLS_CIPHERSUITES", MYSQL_OPT_TLS_CIPHERSUITES, GB_T_STRING},
#endif
#if HAVE_MYSQL_OPT_ZSTD_COMPRESSION_LEVEL
	{ "ZSTD_COMPRESSION_LEVEL", MYSQL_OPT_ZSTD_COMPRESSION_LEVEL, GB_T_INTEGER},
#endif
	{ NULL }
};

#ifdef GB_DB2_MYSQL
static void add_option_value(const char *key, int len, GB_VALUE *value)
#else
static void add_option_value(const char *key, GB_VALUE *value)
#endif
{
	DB_MYSQL_OPTION *p;
	
	union {
		unsigned int _uint;
		unsigned long _ulong;
	} tmp;
	char *sval;
	
	for (p = _options;; p++)
	{
		if (!p->key)
			return;
		
		if (!strcasecmp(p->key, key))
			break;
	}
	
	if (GB.Conv(value, p->type))
		return;
	
	switch(p->cst)
	{
		case MYSQL_OPT_COMPRESS:
			if (value->_boolean.value)
				mysql_options(_options_conn, p->cst, NULL);
			break;
		
		case MYSQL_OPT_PROTOCOL:

			sval = value->_string.value.addr;
			if (!strcasecmp(sval, "DEFAULT"))
				tmp._uint = MYSQL_PROTOCOL_DEFAULT;
			else if (!strcasecmp(sval, "TCP"))
				tmp._uint = MYSQL_PROTOCOL_TCP;
			else if (!strcasecmp(sval, "SOCKET"))
				tmp._uint = MYSQL_PROTOCOL_SOCKET;
			else if (!strcasecmp(sval, "PIPE"))
				tmp._uint = MYSQL_PROTOCOL_PIPE;
			else if (!strcasecmp(sval, "MEMORY"))
				tmp._uint = MYSQL_PROTOCOL_MEMORY;
			else
				return;
			
			mysql_options(_options_conn, p->cst, &tmp._uint);
			break;
		
		case MYSQL_OPT_LOCAL_INFILE:
			
			tmp._uint = value->_boolean.value;
			mysql_options(_options_conn, p->cst, &tmp._uint);
			break;
			
#if HAVE_MYSQL_OPT_SSL_MODE
		case MYSQL_OPT_SSL_MODE:
			
			sval = value->_string.value.addr;
			if (!strcasecmp(sval, "REQUIRED"))
				tmp._uint = SSL_MODE_REQUIRED;
#if HAVE_MYSQL_SSL_MODE_PREFERRED
			else if (!strcasecmp(sval, "PREFERRED"))
				tmp._uint = SSL_MODE_PREFERRED;
#endif
#if HAVE_MYSQL_SSL_MODE_VERIFY_CA
			else if (!strcasecmp(sval, "VERIFY_CA"))
				tmp._uint = SSL_MODE_VERIFY_CA;
#endif
#if HAVE_MYSQL_SSL_MODE_VERIFY_IDENTITY
			else if (!strcasecmp(sval, "VERIFY_IDENTITY"))
				tmp._uint = SSL_MODE_VERIFY_IDENTITY;
#endif
#if HAVE_MYSQL_SSL_MODE_DISABLED
			else if (!strcasecmp(sval, "DISABLED"))
				tmp._uint = SSL_MODE_DISABLED;
#endif
			else
				return;
			
			mysql_options(_options_conn, p->cst, &tmp._uint);
			break;
#endif
		
#if LIBMYSQL_VERSION_ID >= 50700
		case MYSQL_OPT_MAX_ALLOWED_PACKET:
		case MYSQL_OPT_NET_BUFFER_LENGTH:
			
			tmp._ulong = value->_integer.value;
			mysql_options(_options_conn, p->cst, &tmp._ulong);
			break;
#endif

#if HAVE_MYSQL_OPT_SSL_FIPS_MODE
		case MYSQL_OPT_SSL_FIPS_MODE:
			
			sval = value->_string.value.addr;
			if (!strcasecmp(sval, "OFF"))
				tmp._uint = SSL_FIPS_MODE_OFF;
			else if (!strcasecmp(sval, "ON"))
				tmp._uint = SSL_FIPS_MODE_ON;
			else if (!strcasecmp(sval, "STRICT"))
				tmp._uint = SSL_FIPS_MODE_STRICT;
			else
				return;
			
			mysql_options(_options_conn, p->cst, &tmp._uint);
			break;
#endif

		default:
			
			if (p->type == GB_T_BOOLEAN)
				mysql_options(_options_conn, p->cst, &value->_boolean.value);
			else if (p->type == GB_T_INTEGER)
				mysql_options(_options_conn, p->cst, &value->_integer.value);
			else if (p->type == GB_T_STRING)
				mysql_options(_options_conn, p->cst, value->_string.value.addr);
	}
	
}

