#include "wxinc.h"
#include "xvt.h"

#include "wx/filename.h"

#include "../ssa/h/ssadll.h"
#include "../ssa/h/ssaerr.h"

#include <errno.h>

static int _ssa_serial = SSA_UTENTE_NON_LOGGATO; 
static wxString _ssa_module;

static const char* xvt_dongle_sa_id()
{
  static char id[80];
  if (!*id)
  {
    char user[32], host[32];
    const int sess = xvt_sys_get_session_id();
    xvt_sys_get_user_name(user, sizeof(user));
    xvt_sys_get_host_name(host, sizeof(host));
    sprintf(id, "%s@%s:%d", user, host, sess);
  }
  return id;
}

static BOOLEAN xvt_dongle_sa_is_remote_ba0()
{
  BOOLEAN yes = FALSE; 
  const wxFileName argv0 = __argv[0];
  if (wxStricmp(argv0.GetName(), "ba0") == 0)
  {
    char ssaagent[128];
    const int len = xvt_sys_get_profile_string("ssa.ini", "", "SSA-PORT", "", ssaagent, sizeof(ssaagent));
    yes = len > 0;
  }
  return yes;
}

///////////////////////////////////////////////////////////
// TSSA_Pinger
///////////////////////////////////////////////////////////

class TSSA_Pinger : public wxTimer
{
protected:
  virtual void Notify();

public:
  TSSA_Pinger();
};

static TSSA_Pinger* _ssa_timer = NULL;

void TSSA_Pinger::Notify()
{ SSA_Ping(xvt_dongle_sa_id()); }

TSSA_Pinger::TSSA_Pinger()
{
  const int sec = xvt_sys_get_profile_int("ssa.ini", "", "PING-DELAY", 60);
  if (sec > 0)
    Start(sec*1000);
}

///////////////////////////////////////////////////////////
// xvt_dongle_sa_...
///////////////////////////////////////////////////////////

int xvt_dongle_sa_login(const char* module)
{
  int err = _ssa_serial;

  const int nAssYear = xvt_vobj_get_attr(NULL_WIN, ATTR_APPL_VERSION_YEAR);
  if (nAssYear >= 2121)
  {
    if (_ssa_serial < 0)
    {
      err = SSA_Login(xvt_dongle_sa_id(), "Campo");
      if (err == 0)
      {
        err = _ssa_serial = SSA_NumeroSerie("Campo");

        if (_ssa_timer == NULL && xvt_dongle_sa_is_remote_ba0())
          _ssa_timer = new TSSA_Pinger;
      }
    }

    if (_ssa_serial >= 0 && module && *module)
    {
      err = SSA_ApriModulo(xvt_dongle_sa_id(), module);
      if (err == 0)
      {
        if (!_ssa_module.IsEmpty())
          xvt_dongle_sa_logout(_ssa_module);
        _ssa_module = module;
      }
    }
  }
  
  return err;
}

int xvt_dongle_sa_crypt(unsigned short* data)
{
  if (_ssa_serial < 0)
    return SSA_UTENTE_NON_LOGGATO;
  if (data == NULL) 
    return -EACCES;
  data[0] ^= 0xDEAD;
  data[1] ^= 0xBEEF;
  data[2] ^= 0xDEAD;
  data[3] ^= 0xBEEF;
  return 0;
}

int xvt_dongle_sa_logout(const char* module)
{
  int err = SSA_UTENTE_NON_LOGGATO;
  if (_ssa_serial >= 0)
  {
    if (module && *module)
    {
      if (_ssa_module == module)
      {
        err = SSA_ChiudiModulo(xvt_dongle_sa_id(), _ssa_module);
        _ssa_module.Empty();
      }
      else
        err = SSA_MOD_NOTFOUND;
    }
    else
    {
      err = SSA_Logout(xvt_dongle_sa_id(), "Campo");
      if (err == 0)
      {
        _ssa_serial = SSA_UTENTE_NON_LOGGATO;
        _ssa_module.Empty();
        if (_ssa_timer)
        {
          delete _ssa_timer;
          _ssa_timer = NULL;
        }
      }
    }
  }
  return err;
}

int xvt_dongle_sa_test(const char* module)
{
  int err = _ssa_serial; 
  if (err >= 0 && module && *module)
    err = SSA_VerificaModulo("Campo", module);
  return err;
}