/*
 * This file is part of ABCDK.
 * 
 * MIT License
 * 
 */
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <locale.h>
#include "util/general.h"
#include "util/getargs.h"
#include "util/odbc.h"

#if defined(__SQL_H) && defined(__SQLEXT_H)

void _abcdkodbc_print_usage(abcdk_tree_t *args, int only_version)
{
    char name[NAME_MAX] = {0};

    abcdk_proc_basename(name);

    fprintf(stderr, "\n%s 构建 %s\n", name, BUILD_TIME);
    fprintf(stderr, "\n%s 版本 %d.%d.%d\n", name, VERSION_MAJOR, VERSION_MINOR, VERSION_RELEASE);

    if (only_version)
        ABCDK_ERRNO_AND_RETURN0(0);

    fprintf(stderr, "\n摘要:\n");

    fprintf(stderr, "\n%s [ --product < NAME > ] [ OPTIONS ]\n",name);

    fprintf(stderr, "\n%s [ --uri < STRING > ]\n",name);

    fprintf(stderr, "\n描述:\n");

    fprintf(stderr, "\n\t简单的ODBC连接测试工具。\n");

    fprintf(stderr, "\n选项:\n");

    fprintf(stderr, "\n\t--help\n");
    fprintf(stderr, "\t\t显示帮助信息。\n");

    fprintf(stderr, "\n\t--version\n");
    fprintf(stderr, "\t\t显示版本信息。\n");

    fprintf(stderr, "\n\t--product < NAME >\n");
    fprintf(stderr, "\t\t产品名称。支持: DB2/MYSQL/ORACLE/SQLSERVER/POSTGRESQL\n");

    fprintf(stderr, "\n\t--driver\n");
    fprintf(stderr, "\t\t驱动名称。见：/etc/odbcinst.ini\n");

    fprintf(stderr, "\n\t--server < ADDRESS >\n");
    fprintf(stderr, "\t\t服务地址(域名或IP)。默认: localhost\n");

    fprintf(stderr, "\n\t--port < NUMBER >\n");
    fprintf(stderr, "\t\t服务端口。默认: 50000(DB2)/3306(MYSQL)/1521(ORACLE)/1433(SQLSERVER)/5432(POSTGRESQL)\n");

    fprintf(stderr, "\n\t--db < NAME >\n");
    fprintf(stderr, "\t\t数据库名称。 \n");

    fprintf(stderr, "\n\t--uid < NAME >\n");
    fprintf(stderr, "\t\t数据库账户。\n");

    fprintf(stderr, "\n\t--pwd < PASSWROD >\n");
    fprintf(stderr, "\t\t数据库账户密码。 \n");

    fprintf(stderr, "\n\t--uri < STRING >\n");
    fprintf(stderr, "\t\t自定义连接字符串。\n");

    fprintf(stderr, "\n\t--timeout < SECONDS >\n");
    fprintf(stderr, "\t\t超时(秒)。默认: 30\n");

    fprintf(stderr, "\n\t--trace-file < FILE >\n");
    fprintf(stderr, "\t\t指定根踪文件。\n");
    
    ABCDK_ERRNO_AND_RETURN0(0);
}

void _abcdkodbc_work(abcdk_tree_t *args)
{
    abcdk_odbc_t ctx = {0};
    const char *product = NULL;
    const char *driver = NULL;
    const char *server = NULL;
    uint16_t port = 0;
    const char *db = NULL;
    const char *uid = NULL;
    const char *pwd = NULL;
    const char *uri = NULL;
    time_t timeout = 0;
    const char *tracefile = NULL;
    SQLRETURN chk = SQL_ERROR;

    product = abcdk_option_get(args, "--product", 0, NULL);
    driver = abcdk_option_get(args, "--driver", 0, NULL);
    server = abcdk_option_get(args, "--server", 0, "localhost");
    port = abcdk_option_get_int(args, "--port", 0, 0);
    db = abcdk_option_get(args, "--db", 0, NULL);
    uid = abcdk_option_get(args, "--uid", 0, NULL);
    pwd = abcdk_option_get(args, "--pwd", 0, "");
    uri = abcdk_option_get(args, "--uri", 0, NULL);
    timeout = abcdk_option_get_long(args, "--timeout", 0, 30);
    tracefile = abcdk_option_get(args, "--trace-file", 0, NULL);

    /*优先检查自定义是否可用。*/
    if (uri && *uri)
    {
        chk = abcdk_odbc_connect(&ctx, uri, timeout, tracefile);
        goto final;
    }

    if (!product || !*product)
    {
        syslog(LOG_ERR, "'--product NAME' 不能省略，且不能为空。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (abcdk_strcmp(product, "DB2", 0) != 0 &&
        abcdk_strcmp(product, "MYSQL", 0) != 0 &&
        abcdk_strcmp(product, "ORACLE", 0) != 0 &&
        abcdk_strcmp(product, "SQLSERVER", 0) != 0 &&
        abcdk_strcmp(product, "POSTGRESQL", 0) != 0)
    {
        syslog(LOG_ERR, "'--product NAME' 仅支持DB2，MYSQL，ORACLE，SQLSERVER，POSTGRESQL。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (!driver || !*driver)
    {
        syslog(LOG_ERR, "'--driver NAME' 不能省略，且不能为空。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (!server || !*server)
    {
        syslog(LOG_ERR, "'--server ADDRESS' 不能省略，且不能为空。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (port == 0 || port == 65536)
    {
        if(abcdk_strcmp(product,"DB2",0)==0)
            port = 50000;
        else if(abcdk_strcmp(product,"MYSQL",0)==0)
            port = 3306;
        else if(abcdk_strcmp(product,"ORACLE",0)==0)
            port = 1521;
        else if(abcdk_strcmp(product,"SQLSERVER",0)==0)
            port = 1433;
        else if(abcdk_strcmp(product,"POSTGRESQL",0)==0)
            port = 5432;
    }

    if (port == 0 || port == 65536)
    {
        syslog(LOG_ERR, "'--port NUMBER' 范围在1~65535之间(包含)。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (!db || !*db)
    {
        syslog(LOG_ERR, "'--db NAME' 不能省略，且不能为空。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    if (!uid || !*uid)
    {
        syslog(LOG_ERR, "'--uid NAME' 不能省略，且不能为空。");
        ABCDK_ERRNO_AND_GOTO1(EINVAL, final);
    }

    chk = abcdk_odbc_connect2(&ctx,product,driver,server,port,db,uid,pwd,timeout,tracefile);
    ABCDK_ERRNO_AND_GOTO1(0, final);

final:

    fprintf(stdout,"%d\n",((chk == SQL_SUCCESS)?0:1));

    abcdk_odbc_disconnect(&ctx);
}

#endif //defined(__SQL_H) && defined(__SQLEXT_H)


int main(int argc, char **argv)
{
#if defined(__SQL_H) && defined(__SQLEXT_H)

    abcdk_tree_t *args;

    /*中文，UTF-8*/
    setlocale(LC_ALL,"zh_CN.UTF-8");

    args = abcdk_tree_alloc3(1);
    if (!args)
        goto final;

    abcdk_getargs(args, argc, argv, "--");
    //abcdk_option_fprintf(stderr, args);

    abcdk_openlog(NULL, LOG_INFO, 1);

    if (abcdk_option_exist(args, "--help"))
    {
        _abcdkodbc_print_usage(args, 0);
    }
    else if (abcdk_option_exist(args, "--version"))
    {
        _abcdkodbc_print_usage(args, 1);
    }
    else
    {
        _abcdkodbc_work(args);
    }

final:

    abcdk_tree_free(&args);

#else

    abcdk_openlog(NULL, LOG_INFO, 1);
    syslog(LOG_INFO, "当前构建版本未包含此工具。\n");
    errno = EPERM;

#endif //defined(__SQL_H) && defined(__SQLEXT_H)

    return errno;
}