/**
 * $Id$
 * "startup" do SGA daemon (baseado na console do LuaORB)
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// using namespace std;

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "luasocket.h"
#include "oilall.h"
}

#include "sgalib.h"

// ======================================================================

static int _dofile(lua_State* L, char* file);

// ======================================================================
// Bibliotecas Lua.

static luaL_reg loadlibs[] = {
  {"base",   luaopen_base},
  {"package",luaopen_package},
  {"string", luaopen_string},
  {"table",  luaopen_table},
  {"math",   luaopen_math},
  {"io",     luaopen_io},
  {"os",     luaopen_os},
  {"debug",  luaopen_debug},
  {"sga",    luaopen_sga},
  {NULL,     NULL}
};

/**
 * Função principal do SGA.
 *
 */
int main( int argc, char *argv[] )
{
   luaL_reg *ptr;

   // Inicialização de Lua
   lua_State *L = lua_open();

   // bibliotecas
   for( ptr = loadlibs; ptr->func; ptr++) {
    lua_pushcfunction(L, ptr->func);
    lua_pushstring(L, ptr->name);
    lua_call(L, 1, 0);
   }

   // Inicialização do LuaOrb
   luaopen_socket_core(L);
   luapreload_oilall(L);

   // Chamada aos módulo implementados em Lua
#ifdef WITH_LUA
   _dofile(L, "verbose.lua");
   _dofile(L, "./lib/shellExtension.lua");
   _dofile(L, "sga-daemon.lua");
   _dofile(L, "sga-services.lua");
   _dofile(L, "sga-command.lua");
   _dofile(L, "main.lua");
#else
#include "verbose.loh"
#include "lib/shellExtension.loh"
#include "sga-daemon.loh"
#include "sga-services.loh"
#include "sga-command.loh"
#include "main.loh"
#endif
   // Encerramento do programa
   lua_close(L);
   
   return 0;
}

/**
 * Lê e executa um script Lua.
 *
 * Retorno:
 *   0 : Sucesso
 *   1 : Erro
 */
static int _dofile(lua_State* L, char* file)
{
  if (luaL_loadfile(L, file) || lua_pcall(L, 0, 0, 0)) {
    int n = lua_gettop(L);
    const char *msg = lua_tostring (L, n);
    lua_pop(L, 1);
    fprintf(stderr, "%s\n", msg);

    return 1;
  }
  
  return 0;
}

/**
 * Função principal definida para o Windows.
 *
 * Invoca a função main.
 *
 */
#ifdef WIN32
#include <windows.h>
int PASCAL WinMain(HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, 
int ncmdshow) {
  int rc;
  extern int __argc;
  extern char** __argv;
  rc = main(__argc, __argv);
  return (int)rc;
}
#endif
