/*
** 2005 December 14
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file contains a binding of the asynchronous IO extension interface
** (defined in ext/async/sqlite3async.h) to Tcl.
*/

#define TCL_THREADS 
#include <tcl.h>

#ifdef SQLITE_ENABLE_ASYNCIO

#include "sqlite3async.h"
#include "sqlite3.h"
#include <assert.h>

/* From test1.c */
const char *sqlite3TestErrorName(int);


struct TestAsyncGlobal {
  int isInstalled;                     /* True when async VFS is installed */
} testasync_g = { 0 };

TCL_DECLARE_MUTEX(testasync_g_writerMutex);

/*
** sqlite3async_initialize PARENT-VFS ISDEFAULT
*/
static int testAsyncInit(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const char *zParent;
  int isDefault;
  int rc;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "PARENT-VFS ISDEFAULT");
    return TCL_ERROR;
  }
  zParent = Tcl_GetString(objv[1]);
  if( !*zParent ) {
    zParent = 0;
  }
  if( Tcl_GetBooleanFromObj(interp, objv[2], &isDefault) ){
    return TCL_ERROR;
  }

  rc = sqlite3async_initialize(zParent, isDefault);
  if( rc!=SQLITE_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** sqlite3async_shutdown
*/
static int testAsyncShutdown(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3async_shutdown();
  return TCL_OK;
}

static Tcl_ThreadCreateType tclWriterThread(ClientData pIsStarted){
  Tcl_MutexLock(&testasync_g_writerMutex);
  *((int *)pIsStarted) = 1;
  sqlite3async_run();
  Tcl_MutexUnlock(&testasync_g_writerMutex);
  Tcl_ExitThread(0);
  TCL_THREAD_CREATE_RETURN;
}

/*
** sqlite3async_start
**
** Start a new writer thread.
*/
static int testAsyncStart(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  volatile int isStarted = 0;
  ClientData threadData = (ClientData)&isStarted;

  Tcl_ThreadId x;
  const int nStack = TCL_THREAD_STACK_DEFAULT;
  const int flags = TCL_THREAD_NOFLAGS;
  int rc;

  rc = Tcl_CreateThread(&x, tclWriterThread, threadData, nStack, flags);
  if( rc!=TCL_OK ){
    Tcl_AppendResult(interp, "Tcl_CreateThread() failed", 0);
    return TCL_ERROR;
  }

  while( isStarted==0 ) { /* Busy loop */ }
  return TCL_OK;
}

/*
** sqlite3async_wait
**
** Wait for the current writer thread to terminate.
**
** If the current writer thread is set to run forever then this
** command would block forever.  To prevent that, an error is returned. 
*/
static int testAsyncWait(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int eCond;
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "");
    return TCL_ERROR;
  }

  sqlite3async_control(SQLITEASYNC_GET_HALT, &eCond);
  if( eCond==SQLITEASYNC_HALT_NEVER ){
    Tcl_AppendResult(interp, "would block forever", (char*)0);
    return TCL_ERROR;
  }

  Tcl_MutexLock(&testasync_g_writerMutex);
  Tcl_MutexUnlock(&testasync_g_writerMutex);
  return TCL_OK;
}

/*
** sqlite3async_control OPTION ?VALUE?
*/
static int testAsyncControl(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  int rc = SQLITE_OK;
  int aeOpt[] = { SQLITEASYNC_HALT, SQLITEASYNC_DELAY, SQLITEASYNC_LOCKFILES };
  const char *azOpt[] = { "halt", "delay", "lockfiles", 0 };
  const char *az[] = { "never", "now", "idle", 0 };
  int iVal;
  int eOpt;

  if( objc!=2 && objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "OPTION ?VALUE?");
    return TCL_ERROR;
  }
  if( Tcl_GetIndexFromObj(interp, objv[1], azOpt, "option", 0, &eOpt) ){
    return TCL_ERROR;
  }
  eOpt = aeOpt[eOpt];

  if( objc==3 ){
    switch( eOpt ){
      case SQLITEASYNC_HALT: {
        assert( SQLITEASYNC_HALT_NEVER==0 );
        assert( SQLITEASYNC_HALT_NOW==1 );
        assert( SQLITEASYNC_HALT_IDLE==2 );
        if( Tcl_GetIndexFromObj(interp, objv[2], az, "value", 0, &iVal) ){
          return TCL_ERROR;
        }
        break;
      }
      case SQLITEASYNC_DELAY:
        if( Tcl_GetIntFromObj(interp, objv[2], &iVal) ){
          return TCL_ERROR;
        }
        break;

      case SQLITEASYNC_LOCKFILES:
        if( Tcl_GetBooleanFromObj(interp, objv[2], &iVal) ){
          return TCL_ERROR;
        }
        break;
    }

    rc = sqlite3async_control(eOpt, iVal);
  }

  if( rc==SQLITE_OK ){
    rc = sqlite3async_control(
        eOpt==SQLITEASYNC_HALT ? SQLITEASYNC_GET_HALT :
        eOpt==SQLITEASYNC_DELAY ? SQLITEASYNC_GET_DELAY :
        SQLITEASYNC_GET_LOCKFILES, &iVal);
  }

  if( rc!=SQLITE_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3TestErrorName(rc), -1));
    return TCL_ERROR;
  }

  if( eOpt==SQLITEASYNC_HALT ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(az[iVal], -1));
  }else{
    Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
  }

  return TCL_OK;
}

#endif  /* SQLITE_ENABLE_ASYNCIO */

/*
** This routine registers the custom TCL commands defined in this
** module.  This should be the only procedure visible from outside
** of this module.
*/
int Sqlitetestasync_Init(Tcl_Interp *interp){
#ifdef SQLITE_ENABLE_ASYNCIO
  Tcl_CreateObjCommand(interp,"sqlite3async_start",testAsyncStart,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_wait",testAsyncWait,0,0);

  Tcl_CreateObjCommand(interp,"sqlite3async_control",testAsyncControl,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_initialize",testAsyncInit,0,0);
  Tcl_CreateObjCommand(interp,"sqlite3async_shutdown",testAsyncShutdown,0,0);
#endif  /* SQLITE_ENABLE_ASYNCIO */
  return TCL_OK;
}
