#include <iostream>
#include <fstream>

#include <time.h>

#define WINDOWS_EXTRA_LEAN
#include <windows.h>

#pragma warning(disable : 4786)
#define WIN32COMMON
#include <occi.h>

using namespace oracle::occi;
using namespace std;

class campo2pmc
{
  private:
    Environment* env;
    Connection* conn;

  public:
    int executeCommand(const char* command);
    int readCommands(const char* filename);
    void writeResult(const char* resultfile, int error);
    void writeLog(const char* message);
    bool getIniParam(const char* name, string& value);

    campo2pmc();
    ~campo2pmc();
};

campo2pmc::campo2pmc(): env(NULL), conn(NULL)
{
  string username, password, connect;
  getIniParam("Username", username);
  getIniParam("Password", password);
  getIniParam("Connect", connect);
  try
  {
    env = Environment::createEnvironment(Environment::DEFAULT);
    conn = env->createConnection(username, password, connect);
  }
  catch (...)
  {
    conn = NULL;
  }
}

campo2pmc::~campo2pmc() 
{
  if (conn != NULL)
    env->terminateConnection(conn);
  Environment::terminateEnvironment(env);
}

void campo2pmc::writeLog(const char* message)
{
  ofstream logfile("crpa.log", ios::app);

  char date[128];
  char time[128];
  _strtime(time);
  _strdate(date);
  logfile << date << ' ' << time << ' ' << message << endl;
}

void campo2pmc::writeResult(const char* resultfile, int error)
{
  char stringerr[16];
  sprintf(stringerr, "%d", error);
  ::WritePrivateProfileString("Transaction", "Error", stringerr, resultfile);
  ::WritePrivateProfileString("Transaction", "Result", error ? "ERROR": "OK", resultfile);
}

bool campo2pmc::getIniParam(const char* name, string& value)
{
  char val[256];
  bool ok = ::GetPrivateProfileString("Oracle", name, "", val,
                                      sizeof(val), "./crpa.ini") != 0;
  if (ok) value = val;
  return ok;
}


int campo2pmc::executeCommand(const char* command)
{
  int err = 0;
  if (conn != NULL)
  {
    Statement* stmt = conn->createStatement(command);
    if (stmt != NULL)
    {
      try 
      {
        stmt->executeUpdate();
      } 
      catch(SQLException ex)
      {
        err = ex.getErrorCode();
        OCCI_STD_NAMESPACE::string mess = ex.getMessage();
        char message[1024];
        sprintf(message, "Errore %d: %s nel comando %s", err, mess.c_str(), command);
        writeLog(message);
      }
      conn->terminateStatement(stmt);
    }
    else
    {
      char message[1024];
      sprintf(message, "Statement non valido: %s", command);
      writeLog(message);
      err = -2;
    }
  }
  else
  {
    writeLog("Connessione non valida");
    err = -1;
  }
  return err;
}

int campo2pmc::readCommands(const char* filename)
{
  int err = 0;
  ifstream fin(filename);  
  while ((!fin.eof()) && (err==0))
  {
    char line[4096]; 
    fin.getline(line, sizeof(line), '�');
    if (!fin.eof())
    {
      strcat(line,"\n");
      err = executeCommand(line);
    }
  }
  if (err != 0)
    conn->rollback();
  return err;
}

void wake_up_caller()
{
  const unsigned int WM_WAKEUP = RegisterWindowMessage("WAKEUP");
  const HANDLE ht = 0; // GetCurrentProcess();
  PostMessage(HWND_BROADCAST, WM_WAKEUP, (WPARAM)ht, 0L);
}


int main(int argc, char* argv[])
{
  const char* commandfile = "crpa.sql";
  const char* resultfile = "./crpasql.ini";
  if (argc > 1)
      commandfile = argv[1];
  if (argc > 2)
      resultfile = argv[2];
  campo2pmc passa;
  int err = passa.readCommands(commandfile);
  passa.writeResult(resultfile, err);  
  wake_up_caller();
  return err;
}