#include "stdafx.h"

#ifndef _WIN32
#include <sys/types.h>
#include <sys/stat.h>
#endif

// This file contains common TUT test cases for SQL parser, lexer and splitter.

#define VERBOSE_OUTPUT 0

//----------------------------------------------------------------------------------------------------------------------

#include "test.h"
#include "db.mysql.sqlparser/src/mysql_sql_parser_fe.h"
#include "wb_helpers.h"
// only module_sql_parser_test


BEGIN_TEST_DATA_CLASS(module_sql_parser_test)
protected:
  GRTManagerTest grtm;
END_TEST_DATA_CLASS

TEST_MODULE(module_sql_parser_test, "SQL parser test suite");

//----------------------------------------------------------------------------------------------------------------------

static const char *test_function_1_input[] =
{
  "CREATE DATABASE IF NOT EXISTS `i-flow_dev` CHARACTER SET latin1 COLLATE latin1_swedish_ci;",
  "select * from a; select * from b; insert into c values (1,2,3); /* comment ; */; ;",
  "select * from a1; delimiter %%%\n delimiter $$$%%%\n\r select * from a2 $$$%%% select ",
  "select * from x; # comment ; \n\r select * from b",
  "/* comment ; ",
  "\" string ",
  "\' string ",
  "-- comment ; something ",
  "# comment ; something ",
  "select * from z; // blablabla ",
  "DELIMITER |\r\n CREATE1 |CREATE2|",
  "SELECT `тест`",
  "DELIMI",
  "DELIMITER",
  "DELIMITER ",
  "DELIMITER |\r\nx|",
  "DELIMITER //\r\nSELECTz1//SELECTz2",
  NULL
};

static const char *test_function_1_output[] =
{
  "CREATE DATABASE IF NOT EXISTS `i-flow_dev` CHARACTER SET latin1 COLLATE latin1_swedish_ci",

  "select * from a",
  " select * from b",
  " insert into c values (1,2,3)",
  " /* comment ; */",
  //" ",  // empty statments are never returned

  "select * from a1",
  " select * from a2 ",
  " select ",

  "select * from x",
  " # comment ; \n\r select * from b",

  "/* comment ; ",

  "\" string ",

  "\' string ",

  "-- comment ; something ",

  "# comment ; something ",

  "select * from z",
  " // blablabla ",

  " CREATE1 ",
  "CREATE2",

  "SELECT `тест`",

  "DELIMI",

  "DELIMITER",

  "DELIMITER ",

  "x",

  "SELECTz1",
  "SELECTz2"
};

static int test_function_1_output_index;
static bool test_function_1_success_flag;

int test_function_1_cb(void* user_data, const MyxStatementParser *splitter, const char *sql, const MyxSQLTreeItem *tree, int lineno, int err_tok_line_pos, int err_tok_len, const std::string &err_msg)
{
  test_function_1_success_flag &= (strcmp(sql, test_function_1_output[test_function_1_output_index++]) == 0);
  return 0;
}

TEST_FUNCTION(1)
{
  test_function_1_output_index= 0;
  test_function_1_success_flag= true;

  Mysql_sql_parser_fe sql_parser_fe(grtm.get_grt());
  sql_parser_fe.ignore_dml = false;

  for(int i= 0; test_function_1_input[i] != NULL; i++)
  {
    sql_parser_fe.parse_sql_script(test_function_1_input[i], test_function_1_cb, reinterpret_cast<void *>(i));
    ensure("test 20", test_function_1_success_flag);
  }
}

static int test_function_2_counter;

int test_function_2_cb(void* user_data, const MyxStatementParser *splitter, const char *sql, const MyxSQLTreeItem *tree, int lineno, int err_tok_line_pos, int err_tok_len, const std::string &err_msg)
{
  test_function_2_counter++;
  return 0;
}

TEST_FUNCTION(2)
{
  Mysql_sql_parser_fe sql_parser_fe(grtm.get_grt());
  sql_parser_fe.ignore_dml = false;

  test_function_2_counter= 0;
  sql_parser_fe.parse_sql_script_file("data/db/menagerie-db/cr_event_tbl.sql", test_function_2_cb, NULL);
  ensure("test 25 (1)", test_function_2_counter == 2);

  test_function_2_counter= 0;
  sql_parser_fe.parse_sql_script_file("data/db/menagerie-db/cr_pet_tbl.sql", test_function_2_cb, NULL);
  ensure("test 25 (2)", test_function_2_counter == 2);

  test_function_2_counter= 0;
  sql_parser_fe.parse_sql_script_file("data/db/menagerie-db/ins_puff_rec.sql", test_function_2_cb, NULL);
  ensure("test 25 (3)", test_function_2_counter == 1);

  test_function_2_counter= 0;
  sql_parser_fe.parse_sql_script_file("data/db/menagerie-db/load_pet_tbl.sql", test_function_2_cb, NULL);
  ensure("test 25 (4)", test_function_2_counter == 2);

  test_function_2_counter= 0;
  sql_parser_fe.parse_sql_script_file("data/db/sakila-db/sakila-schema.sql", test_function_2_cb, NULL);
  ensure("test 25 (5)", test_function_2_counter == 41);
}

int test_function_30_cb(void* user_data, const MyxStatementParser *splitter, const char *sql, const MyxSQLTreeItem *tree, int lineno, int err_tok_line_pos, int err_tok_len, const std::string &err_msg)
{
  return 0;
}

#ifdef __WIN__

// performance test
TEST_FUNCTION(3)
{
  const char *filename= "data/db/sakila-db/sakila-data.sql";

  struct _stat statbuf;

//  _stat(filename, &statbuf);
  ensure("make line above compilable",false);

  test_time_point t1;
  Mysql_sql_parser_fe sql_parser_fe(grtm.get_grt());
  sql_parser_fe.ignore_dml = false;
  sql_parser_fe.parse_sql_script_file(filename, test_function_30_cb, NULL);

#if VERBOSE_OUTPUT
  test_time_point t2;

  float time_rate= ((float)1000.)/(t2 - t1).get_ticks();
  float size_per_sec= ((float)statbuf.st_size)*time_rate/1024/1024;
  std::cout << "Splitter performance test: " << std::endl 
    << "sakila-data.sql was processed in " << (t2 - t1) << " [" << size_per_sec << " MB/sec]" << std::endl;
#endif
}

#endif

END_TESTS;

//----------------------------------------------------------------------------------------------------------------------

