#define EMBEDDED_LIBRARY
#define MYSQL_YACC
#define MYSQL_LEX012
#define MYSQL_SERVER
#if defined(MYSQL_CLIENT)
#undef MYSQL_CLIENT
#endif

#include <my_config.h>
#include <mysql.h>
#include <my_sys.h>
#include <my_global.h>
#include <my_dbug.h>
#include <my_base.h>
#include <sql_list.h>
#include <mysqld_error.h>
#include <sql_class.h>
#include <sql_lex.h>
#include <embedded_priv.h>
#include <sql_class.h>
#include <sql_lex.h>
#include <sql_parse.h>
#include <errmsg.h>
#include <client_settings.h>
#include <set_var.h>
#include <strfunc.h>
#include <item_func.h>

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

/**
 * This represents a single worker thread which creates and parses
 * queries.
 */
static bool running = true;
static const char *query_str = "SELECT 1";
static const int query_len = strlen(query_str);

void stop()
{
    running = false;
}

void* test_thr(void *data)
{
    if(mysql_thread_init())
    {
        printf("mysql_thread_init failed.\n");
        return NULL;
    }
    char query_buff[1024];
    strcpy(query_buff, query_str);

    while(running)
    {
        /** Initialize MYSQL */
        char* db = (char*) "test_db";
        char* user = (char*)"user";
        unsigned long f = 0;
        MYSQL *mysql = mysql_init(NULL);
        if(mysql == NULL)
        {
            printf("mysql_init returned NULL\n");
            break;
        }

        f |= mysql->options.client_flag;
        
        /* Send client information for access check */
        f |= CLIENT_CAPABILITIES;
        
        if (f & CLIENT_MULTI_STATEMENTS) {
            f |= CLIENT_MULTI_RESULTS;
        }
        /**
         * No compression in embedded as we don't send any data,
         * and no pluggable auth, as we cannot do a client-server dialog
         */
        f &= ~(CLIENT_COMPRESS | CLIENT_PLUGIN_AUTH);
        
        if (mysql->options.db != NULL) {
            f |= CLIENT_CONNECT_WITH_DB;
        }

        mysql_options(mysql, MYSQL_READ_DEFAULT_GROUP, "test");
        mysql_options(mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, NULL);
        mysql->methods = &embedded_methods;
        mysql->user    = my_strdup(user, MYF(0));
        mysql->db      = my_strdup(db, MYF(0));
        mysql->passwd  = NULL;

        /** Create THD */
        THD *thd = (THD *)create_embedded_thd(f);
        mysql->thd = thd;
        init_embedded_mysql(mysql, f);

        thd->clear_data_list();
        thd->current_stmt = NULL;
        thd->store_globals();

        /** Add the query */
        free_old_query(mysql);
        thd->extra_length = query_len;
        thd->extra_data = query_buff;
        alloc_query(thd, query_str, query_len);

        /** Parse query */
        Parser_state parser_state;
        bool         failp = FALSE;
        const char*  virtual_db = "test_db";

        parser_state.init(thd, thd->query(), thd->query_length());
        thd->reset_for_next_command();
        thd->set_db(virtual_db, strlen(virtual_db));
        parse_sql(thd, &parser_state, NULL);

        /** Free everything */
        thd->end_statement();
        (*mysql->methods->free_embedded_thd)(mysql);
        mysql_close(mysql);
    }
    mysql_thread_end();
    return NULL;
}
