#include "cgi.h"
#include "db.h"
#include "html.h"
#include "session.h"

#include <stdio.h>

int main(void) {
    Session session;
    int logged_in = session_load(&session);
    Db db;
    SQLHSTMT stmt = SQL_NULL_HSTMT;
    SQLRETURN ret;
    SQLINTEGER user_id = logged_in ? session.user_id : 0;
    SQLLEN user_id_ind = 0;

    SQLINTEGER id;
    SQLCHAR title[256];
    SQLCHAR body[4096];
    SQLCHAR created_at[32];
    SQLINTEGER is_public;
    SQLLEN id_ind, title_ind, body_ind, created_ind, public_ind;

    db_init(&db);
    if (!db_connect(&db)) {
        cgi_status_header("500 Internal Server Error", "text/plain");
        printf("database connection failed\n");
        return 1;
    }

    ret = SQLAllocHandle(SQL_HANDLE_STMT, db.dbc, &stmt);
    if (!odbc_succeeded(ret)) {
        cgi_status_header("500 Internal Server Error", "text/plain");
        goto cleanup;
    }

    if (logged_in) {
        SQLCHAR sql[] =
            "SELECT id, title, body, is_public, created_at FROM diary "
            "WHERE is_public = 1 OR user_id = ? ORDER BY created_at DESC";
        ret = SQLPrepare(stmt, sql, SQL_NTS);
        if (odbc_succeeded(ret)) {
            ret = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &user_id, 0, &user_id_ind);
        }
        if (odbc_succeeded(ret)) {
            ret = SQLExecute(stmt);
        }
    } else {
        SQLCHAR sql[] =
            "SELECT id, title, body, is_public, created_at FROM diary "
            "WHERE is_public = 1 ORDER BY created_at DESC";
        ret = SQLExecDirect(stmt, sql, SQL_NTS);
    }

    if (!odbc_succeeded(ret)) {
        cgi_status_header("500 Internal Server Error", "text/plain");
        goto cleanup;
    }

    cgi_header("text/html");
    printf("<!DOCTYPE html><html lang=\"ja\"><body>\n");
    printf("<h1>日記一覧</h1>\n");
    if (logged_in) {
        printf("<p><a href=\"/cgi-bin/diary_form.cgi\">日記を書く</a></p>\n");
    }

    while ((ret = SQLFetch(stmt)) != SQL_NO_DATA) {
        if (!odbc_succeeded(ret)) {
            break;
        }
        SQLGetData(stmt, 1, SQL_C_SLONG, &id, 0, &id_ind);
        SQLGetData(stmt, 2, SQL_C_CHAR, title, sizeof(title), &title_ind);
        SQLGetData(stmt, 3, SQL_C_CHAR, body, sizeof(body), &body_ind);
        SQLGetData(stmt, 4, SQL_C_SLONG, &is_public, 0, &public_ind);
        SQLGetData(stmt, 5, SQL_C_CHAR, created_at, sizeof(created_at), &created_ind);

        printf("<article>\n<h2>");
        html_escape_print(stdout, (const char *)title);
        printf("</h2>\n<p>");
        html_escape_print(stdout, (const char *)body);
        printf("</p>\n<p>");
        html_escape_print(stdout, (const char *)created_at);
        printf(" / %s</p>\n", is_public ? "公開" : "非公開");
        printf("</article>\n");
    }

    printf("</body></html>\n");

cleanup:
    if (stmt != SQL_NULL_HSTMT) {
        SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    }
    db_close(&db);
    return 0;
}
