
/*
 * Copyright (C) Igor Sysoev
 */

#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_mysql.h>
#include <ngx_http.h>


typedef struct {
    ngx_peer_addr_t  *peers;
    ngx_uint_t        npeers;
} ngx_http_mysql_test_conf_t;


static void ngx_http_mysql_auth(ngx_mysql_t *m);
static void ngx_http_mysql_done(ngx_mysql_t *m);
static void *ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf);

static ngx_command_t  ngx_http_mysql_test_commands[] = {

    { ngx_string("mysql_test"),
      NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_http_mysql_test,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

      ngx_null_command
};


static ngx_http_module_t  ngx_http_mysql_test_module_ctx = {
    NULL,                          /* preconfiguration */
    NULL,                          /* postconfiguration */

    NULL,                          /* create main configuration */
    NULL,                          /* init main configuration */

    NULL,                          /* create server configuration */
    NULL,                          /* merge server configuration */

    ngx_http_mysql_test_create_loc_conf,  /* create location configuration */
    NULL                           /* merge location configuration */
};


ngx_module_t  ngx_http_mysql_test_module = {
    NGX_MODULE_V1,
    &ngx_http_mysql_test_module_ctx, /* module context */
    ngx_http_mysql_test_commands,   /* module directives */
    NGX_HTTP_MODULE,               /* module type */
    NULL,                          /* init master */
    NULL,                          /* init module */
    NULL,                          /* init process */
    NULL,                          /* init thread */
    NULL,                          /* exit thread */
    NULL,                          /* exit process */
    NULL,                          /* exit master */
    NGX_MODULE_V1_PADDING
};


static ngx_str_t  ngx_mysql_login = ngx_string("root");
static ngx_str_t  ngx_mysql_passwd = ngx_string("tp");
static ngx_str_t  ngx_mysql_database = ngx_string("mysql");
static ngx_str_t  ngx_mysql_command_query =
    ngx_string("select * from user");


static ngx_int_t
ngx_http_mysql_test_handler(ngx_http_request_t *r)
{
    ngx_int_t                    rc;
    ngx_mysql_t                 *m;
    ngx_http_mysql_test_conf_t  *mtcf;

    mtcf = ngx_http_get_module_loc_conf(r, ngx_http_mysql_test_module);

    m = ngx_pcalloc(r->pool, sizeof(ngx_mysql_t));

    if (m == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    m->pool = r->pool;
    m->handler = ngx_http_mysql_auth;
    m->data = r;

    m->login = &ngx_mysql_login;
    m->passwd = &ngx_mysql_passwd;
    m->database = &ngx_mysql_database;

    /* STUB */
    m->peer.sockaddr = mtcf->peers[0].sockaddr;
    m->peer.socklen = mtcf->peers[0].socklen;
    m->peer.name = &mtcf->peers[0].name;
    m->peer.tries = mtcf->npeers;
    m->peer.get = ngx_event_get_peer;
    /**/
    m->peer.log = r->connection->log;
    m->peer.log_error = NGX_ERROR_ERR;

    rc = ngx_mysql_connect(m);

    if (rc == NGX_OK || rc == NGX_AGAIN) {
        return NGX_DONE;
    }

    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}


static void
ngx_http_mysql_auth(ngx_mysql_t *m)
{
    ngx_http_request_t  *r;

    r = m->data;

    if (m->state != NGX_OK) {
        ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT);
        return;
    }

    m->query.len = NGX_MYSQL_CMDPKT_LEN + ngx_mysql_command_query.len;

    m->query.data = ngx_pnalloc(r->pool, m->query.len);
    if (m->query.data == NULL) {
        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
        return;
    }

    ngx_memcpy(m->query.data + NGX_MYSQL_CMDPKT_LEN,
               ngx_mysql_command_query.data, ngx_mysql_command_query.len);

    m->handler = ngx_http_mysql_done;

    ngx_mysql_query(m);
}


static void
ngx_http_mysql_done(ngx_mysql_t *m)
{
    ngx_http_request_t  *r;

    r = m->data;

    ngx_http_finalize_request(r, NGX_HTTP_NO_CONTENT);
}


static void *
ngx_http_mysql_test_create_loc_conf(ngx_conf_t *cf)
{
    ngx_http_mysql_test_conf_t  *conf;

    conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_mysql_test_conf_t));
    if (conf == NULL) {
        return NGX_CONF_ERROR;
    }

    return conf;
}

static char *
ngx_http_mysql_test(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_mysql_test_conf_t  *mtcf = conf;

    ngx_str_t                 *value;
    ngx_url_t                  u;
    ngx_http_core_loc_conf_t  *clcf;

    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
    clcf->handler = ngx_http_mysql_test_handler;

    value = cf->args->elts;

    ngx_memzero(&u, sizeof(ngx_url_t));

    u.url = value[1];
    u.default_port = 3306;

    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
        if (u.err) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "%s in upstream \"%V\"", u.err, &u.url);
        }

        return NGX_CONF_ERROR;
    }

    mtcf->peers = u.addrs;
    mtcf->npeers = u.naddrs;

    return NGX_CONF_OK;
}
