#include "baseserv.h"

#include "dongle.h"

///////////////////////////////////////////////////////////
// TLicenseServer
///////////////////////////////////////////////////////////

class TLicenseServer : public TBaseServerApp
{
private:
	TDongle m_Dongle;

protected:  
	virtual const wxChar* GetAppName() const;
  void AddNumber(TXmlItem& tr, int n) const;
  wxString Garble(unsigned short n, const wxDateTime& date) const;

	virtual bool Initialization();
	virtual bool Deinitialization();
  virtual void SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer);
  virtual void ProcessFormCommand(wxString cmd, wxSocketBase& outs);

public:
	bool IsMagicName(wxString& strFilename) const;
  void GenerateIndex(wxString& strFilename);
	void GenerateFile(wxString& strFile);

  wxString Garble(unsigned short nDongle, unsigned short nNumber) const;

};

wxString TLicenseServer::Garble(unsigned short nMaster, unsigned short nDongle,
                                long nNumber) const
{
  unsigned short data[4];
  data[0] = nMaster;
  data[1] = nDongle;
  data[2] = (unsigned short)(nNumber >> 16);
  data[3] = (unsigned short)(nNumber & 0xFFFF);
  m_Dongle.garble(data);
  return wxString::Format("%04X%04X%04X%04X", data[0], data[1], data[2], data[3]);
}

// Implementare almeno queste due funzioni pure virtuali

const wxChar* TLicenseServer::GetAppName() const
{	return "Licenser"; }

bool TLicenseServer::IsMagicName(wxString& strFilename) const
{
  wxString strName;
	wxSplitPath(strFilename, NULL, &strName, NULL);
  strName.MakeLower();
  const int q = strName.Find('?');
	if (q > 0)
	  strName.Truncate(q);

	if (strName == "index" || strName == "modules")
	{
		strFilename = strName;
		return true;
	} else
	if (strName == "log")
	{
		strFilename = GetLogFileName();
	} else
	if (strName == "activate" || strName == "deactivate" || 
		  strName == "year" || strName == "maxusers" || strName == "kill")
	{
		return true;
	}

  return false;
}

void TLicenseServer::AddNumber(TXmlItem& tr, int n) const
{
	TXmlItem& td = tr.AddChild("td");
	td.SetAttr("align", "right");
	td << wxString::Format("%d", n);
}

void TLicenseServer::GenerateIndex(wxString& strFilename)
{
	TXmlItem html; 
	TXmlItem& body = CreatePageBody(html);

	TXmlItem& title = body.AddChild("h1").AddChild("center");
	if (m_Dongle.Ok())
	{
  	TXmlItem& tr = title.AddChild("table").SetAttr("width", "40%").AddChild("tr");
		
		TXmlItem& td = tr.AddChild("td").SetAttr("width", "30%");
		const bool hard = m_Dongle.hardware() == _dongle_hardlock;
		TXmlItem& img = td.AddChild("img");
		img.SetAttr("src", hard ? "hardlock.gif" : "eutron.gif");

		tr.AddChild("td").SetAttr("align", "center").AddChild("h1") << (hard ? "Hardlock EYE" : "Eutron Smartkey");
	}
	else
	{
		title << "No Dongle Connected!";
	}
	body.AddChild("br");

	TXmlItem& table = body.AddChild("center").AddChild("table");
  table.SetAttr("border", "1");
	table.SetAttr("width", "70%");

	TXmlItem& tr0 = body.AddChild("tr");
  tr0.AddChild("td") << "Serial Number";
	AddNumber(tr0, m_Dongle.Number());
	
	TXmlItem& tr1 = body.AddChild("tr");
  TXmlItem& ay = tr1.AddChild("td").AddChild("a");
  ay.SetAttr("href", "year.htm") << "Assistance Year";
	AddNumber(tr1, m_Dongle.YearAssist());

	TXmlItem& tr2 = body.AddChild("tr");
	TXmlItem& mu = tr2.AddChild("td").AddChild("a");
  mu.SetAttr("href", "maxusers.htm") << "Maximum Users";
	AddNumber(tr2, m_Dongle.MaxUsers());

	TXmlItem& tr5 = body.AddChild("tr");
  tr5.AddChild("td") << "Host name:port";
  wxIPV4address addr; addr.AnyAddress(); addr.Service(GetDefaultPort());
  wxString strHP; strHP << addr.Hostname() << ":" << addr.Service();
  tr5.AddChild("td").SetAttr("align", "right") << strHP;

	TXmlItem& tr6 = body.AddChild("tr");
  TXmlItem& al = tr6.AddChild("td").AddChild("a");
	al.SetAttr("href", "Log"); al << "Log File";

	TXmlItem& tr7 = body.AddChild("tr");
  TXmlItem& as = tr7.AddChild("td").AddChild("a");
	as.SetAttr("href", "stop.cgi"); as << "Stop the Server";

	strFilename = GetTempFilename();
	html.Save(strFilename);
}

void TLicenseServer::GenerateFile(wxString& strFilename)
{
  const int q = strFilename.Find('?');
	wxString strArgs;
	if (q > 0)
	{
		strArgs = strFilename.Mid(q+1);
	  strFilename.Truncate(q);
	}

  wxString strName;
	wxSplitPath(strFilename, NULL, &strName, NULL);
  strName.MakeLower();

	if (strName == "index")
	{
		GenerateIndex(strFilename);
	} else
	if (strName == "modules")
	{
	} else
	if (strName == "users")
	{
	} else
	if (strName == "log")
	{
		strFilename = GetLogFileName();
	} else
	if (strName == "activate")
	{
	} else
	if (strName == "deactivate")
	{
	} else
	if (strName == "year")
	{
	} else
	if (strName == "maxusers")
	{
	} else
	if (strName == "kill")
	{
	}
}

void TLicenseServer::ProcessFormCommand(wxString cmd, wxSocketBase& outs)
{
  const int stop = cmd.Find(" HTTP");
	wxString strFileName = cmd.Mid(5, stop-5).Trim();

	wxString strName, args;
	wxSplitPath(strFileName, NULL, &strName, NULL);
	strName.MakeLower();

	const int pos = cmd.Find("\r\n\r\n");
	if (pos > 0)
	  args = cmd.Mid(pos+4);

	THashTable hashArgs(13);
  ParseArguments(args, hashArgs);

	if (strName == "activate")
	{
	} else
	if (strName == "deactivate")
	{
	} else
	if (strName == "year")
	{
	} else
	if (strName == "maxusers")
	{
	} else
		MessageBox("ERROR!", "You supplied the wrong activation code", outs);
}

bool TLicenseServer::Initialization()
{
	const int delay =	GetConfigInt("Delay", 10);
	for (int i = 0; i < 3; i++)
	{
		if (m_Dongle.Login())
			break;
		wxSleep(delay);
	}

	return true;
}

bool TLicenseServer::Deinitialization()
{
	m_Dongle.Logout();
	return true;
}

void TLicenseServer::SoapProcessMethod(const TXmlItem& xmlMethod, TXmlItem& xmlAnswer)
{
	const wxString& strMethod = xmlMethod.GetTag();
	
  if (strMethod == "m:ActivateYear") // ActivateYear(int master, int dongle, int year, string pwd)
  {
    const int nMaster = xmlMethod.GetSoapInt("master");
    if (nMaster <= 0 || nMaster >= 1000)
    {
      xmlAnswer.AddSoapInt("error", 1);
      xmlAnswer.AddSoapString("description", "Invalid Master Dongle number");
      return;
    }

    const int nDongle = xmlMethod.GetSoapInt("dongle");
    if (nDongle < 1000 || nDongle >= 10000)
    {
      xmlAnswer.AddSoapInt("error", 1);
      xmlAnswer.AddSoapString("description", "Invalid Dongle number");
      return;
    }
    
    const int nYear = xmlMethod.GetSoapInt("year");
    if (nYear < 2000 || nYear > 3000)
    {
      xmlAnswer.AddSoapInt("error", 2);
      xmlAnswer.AddSoapString("description", "Invalid Year");
      return;
    }

    const wxString strPwd = xmlMethod.GetSoapInt("password");

  }
}

// Istanziare l'applicazione principale

IMPLEMENT_APP(TLicenseServer)