#include <ctype.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <dirent.h>
#include "globals.h"
#include "utils.h"

/*
Zwraca status w odpowiedniej postaci dla jabbera
*/

int
jbr_status (char *rstatus, int sizeofrstatus, int graph, int xemot, int icgi)
{
  int s = 0;
  char poms[300];

  if (strcmp (rstatus, "online") == 0)
    s = 0;
  if (strcmp (rstatus, "dnd") == 0)
    s = 1;
  if (strcmp (rstatus, "chat") == 0)
    s = 2;
  if (strcmp (rstatus, "offline") == 0)
    s = 3;
  if (strcmp (rstatus, "away") == 0)
    s = 4;
  if (strcmp (rstatus, "xa") == 0)
    s = 5;

  if (graph == 0)
    {
      sprintf (poms, "%s ",
	       (s == 0) ? "onl" : (s == 1) ? "dnd" : (s == 2) ? "cht" : (s ==
									 3) ?
	       "off" : (s == 4) ? "awa" : "xaw");
    }
  else
    {
      sprintf (poms, "<img src=\"%s%s%s\" alt=\"%s\"/>",
	       (icgi) ? "/rtg/" : "?",
	       (s == 0) ? "jonl" : (s == 1) ? "jdnd" : (s ==
							2) ? "jcht" : (s ==
								       3) ?
	       "joff" : (s == 4) ? "jawa" : "jxaw",
	       (xemot) ? ".gif" : ".wbmp",
	       (s == 0) ? "onl" : (s == 1) ? "dnd" : (s == 2) ? "cht" : (s ==
									 3) ?
	       "off" : (s == 4) ? "awa" : "xaw");
    }

  sprintf (rstatus, "%.*s", sizeofrstatus - 1, poms);
  return 0;
}

int
gettnickr (char *uin, char *tnick, long int sizeoftnick)
{
  char linia[201], *nick, *end;
  FILE *wap;

  memset (tnick, sizeoftnick, 0);
  if ((wap = vfopen ("r", "%.100s/wap-roster", home)))
    {
      while (fgets (linia, 200, wap))
	{
	  nick = (char *) index (linia, ';');
	  if (nick)
	    {
	      nick++[0] = 0;
	      end = (char *) index (nick, ';');
	      if (end)
		{
		  end[0] = 0;
		  if (strcmp (uin, linia) == 0)
		    {
		      snprintf (tnick, sizeoftnick, "%s", nick);
		      fclose (wap);
		      return 0;
		    }
		}
	    }
	}
      //not found
      fclose (wap);
    }
  return 0;
}

int
gettnick (char *uin, char *tnick, long int sizeoftnick)
{
  char linia[201], *n, *m, *n1;
  FILE *wap;

  if ((wap = vfopen ("r", "%.100s/userlist", home)))
    {
      while (fgets (linia, 200, wap))
	{
	  n = (char *) index (linia, ';');
	  if (n)
	    n = (char *) index (n + 1, ';');
	  if (n)
	    n = (char *) index (n + 1, ';');
	  if (n)
	    {
	      // w n+1 jest nick
	      m = (char *) index (n + 1, ';');
	      if (m)
		m++[0] = 0;
	      if (m)
		m = (char *) index (m, ';');
	      if (m)
		m = (char *) index (m + 1, ';');

	      n1 = (char *) index (m + 1, ';');
	      if (n1 != NULL)
		n1[0] = 0;
	      n1 = (char *) index (m + 1, 10);
	      if (n1 != NULL)
		n1[0] = 0;
	      n1 = (char *) index (m + 1, 13);
	      if (n1 != NULL)
		n1[0] = 0;

	      if (m + 1)
		{
		  if (strcmp (uin, m + 1) == 0)
		    {
		      snprintf (tnick, sizeoftnick, "%s", n + 1);
		      fclose (wap);
		      return 0;
		    }
		}
	    }
	}
      //not found
      fclose (wap);
    }
  return 0;
}

int
gettuin (char *nick, char *targetuin, long int sizeoftargetuin)
{
  char linia[201], *n, *m;
  FILE *wap;

  if ((wap = vfopen ("r", "%.100s/userlist", home)))
    {
      while (fgets (linia, 200, wap))
	{
	  n = (char *) index (linia, ';');
	  if (n)
	    n = (char *) index (n + 1, ';');
	  if (n)
	    n = (char *) index (n + 1, ';');
	  if (n)
	    {
	      if (strncmp (n + 1, nick, strlen (nick)) == 0)
		{
		  // znaleziono!
		  fclose (wap);

		  m = (char *) index (n + 1, ';');
		  if (m)
		    m = (char *) index (m + 1, ';');
		  if (m)
		    m = (char *) index (m + 1, ';');

		  n = (char *) index (linia, 10);
		  if (n != NULL)
		    n[0] = 0;
		  n = (char *) index (linia, 13);
		  if (n != NULL)
		    n[0] = 0;

		  if (m)
		    {
		      snprintf (targetuin, sizeoftargetuin, "%ld",
				atol (m + 1));
		    }
		  return 0;
		}
	    }
	}
      //not found
      fclose (wap);
    }
  return 0;
}


/*
licznik bajtow nadanych i wyslanych z rtg z podzialem
na sesje freeblwr
*/

int
countersadd (char *pathhome, long int in, long int out)
{
  char pom[255], ins[42], outs[42];
  FILE *plik;

  sprintf (ins, "0");
  sprintf (outs, "0");
  if (debug > 1)
    printf ("[rtg] %s in %ld out %ld\n", pathhome, in, out);
  snprintf (pom, sizeof (pom), "%s/wap-counters", pathhome);
  if ((plik = fopen (pom, "r")))
    {
      if (!feof (plik))
	fgets (ins, 41, plik);
      if (!feof (plik))
	fgets (outs, 41, plik);
      fclose (plik);
    }
  if ((plik = fopen (pom, "w")))
    {
      fprintf (plik, "%ld\n%ld\n", atol (ins) + in, atol (outs) + out);
      fclose (plik);
    }
  return 0;
}

/*
funkcja czyści katalog slotu o podanym numerze
gdy kat==1 kasuje również sam katalog
*/

int
clrdir (int slot, int kat)
{
  struct dirent **namelist;
  char wapfile[201], tmp[201];
  int n, k;

  //wyczysc katalog
  snprintf (tmp, sizeof (tmp), "%s/%d/", home, slot);
  n = scandir (tmp, &namelist, 0, alphasort);
  if (n < 0)
    {
      // jakis problem z lista katalogow
      if (debug > 0)
	printf ("[%d] Problem z katalogiem: %s\n", slot, tmp);
      return 0;
    }
  else
    {
      k = n;
      while (n--)
	{
	  snprintf (wapfile, sizeof (wapfile), "%s%s", tmp,
		    namelist[k - n - 1]->d_name);
	  unlink (wapfile);
	}
      free (namelist[k - n - 1]);
    }
  free (namelist);

  if (kat == 1)
    {
      snprintf (tmp, sizeof (tmp), "%s/%d/", home, slot);
      rmdir (tmp);
    }

  return 0;
}

/*
funkcja szuka wolnego slotu dla freeblwr mode
jeśli go znajdzie zwraca jego numer, jeśli go nie znajdzie
zwraca zero
*/

int
findslot (int maxslots)
{
  int i, fs = 0;
  char tmp[201];
  struct stat buf;
  time_t tczas;
  long int czas = 0;

  time (&tczas);

//szukam wogole wolnego slotu
  for (i = 1; i <= maxslots; i++)
    {
      snprintf (tmp, sizeof (tmp), "%.150s/%d", home, i);
      if (mkdir (tmp, 0700) == 0)
	{			// znaleziono slot
	  if (debug > 0)
	    printf ("[search] Znaleziono wolny slot %d\n", i);
	  return i;
	}
    }

//szukam najstarszego slotu
  if (debug > 0)
    printf ("[search] Brak wolnych slotow szukam najstarszego\n");
  for (i = 1; i <= maxslots; i++)
    {
      snprintf (tmp, sizeof (tmp), "%.150s/%d/wap-query.log", home, i);
      if (lstat (tmp, &buf) == 0)
	{
	  if (buf.st_mtime < czas || czas == 0)
	    {
	      czas = buf.st_mtime;
	      fs = i;
	    }
	}
    }
  if (debug > 0)
    printf ("[search] Najstarszy slot %d\n", fs);

  if (fs == 0)
    return 0;

// jeśli najstarsze gniazdo było urzywane w ciągu 10 minut to
// go nie można urzywać

  if ((tczas - czas) < 600)
    {
      if (debug > 0)
	printf ("[search] Slot %d nadal urzywany\n", fs);
      return 0;
    }

//jesli bardzo stary
  snprintf (tmp, sizeof (tmp), "%.150s/%d/wap-query.log", home, fs);
  if (unlink (tmp) == 0)
    {
      FILE *pwap;

      //tylko 1 proces tu wejdzie jesli szukalo wiecej (jeden zdarzy odlinkowac plik)
      //mozna by poszukac jeszcze, ale nie ma wogole wolnych
      //a jeszcze 2 naraz sie dobija

      //zatrzymaj ekg

      if (debug > 0)
	printf ("[search] slot %d przedawniony\n", fs);
      snprintf (tmp, sizeof (tmp), "%.150s/%d/pipewap", home, fs);
      if ((pwap = fopen (tmp, "r+")))
	{
	  //znaczy sie dziala
	  fprintf (pwap, "/quit\n");
	  fclose (pwap);
	  sleep (2);		//daj mu czas na zamkniecie
	}

      clrdir (fs, 0);

      return fs;
    }				//udal sie unlink

//sorry, no free slots
  return 0;
}

/*
Funkcja pisze w rurke do ekg
zwraca 0 gdy się nie udało otworzyc rurki lub 1 gdy się udało
*/

int
doekg (const char *a, ...)
{
  va_list ap;
  FILE *wap;

  if ((wap = vfopen ("r+", "%s/pipewap", home)))
    {
      va_start (ap, a);
      vfprintf (wap, a, ap);
      va_end (ap);
      fclose (wap);
      return 1;
    }
  return 0;
}

/*
Funkcja pisze w rurke do jabbera
zwraca 0 gdy się nie udało otworzyc rurki lub 1 gdy się udało
*/

int
dojbr (const char *a, ...)
{
  va_list ap;
  FILE *wap;

  if ((wap = vfopen ("r+", "%s/pipewapj", home)))
    {
      va_start (ap, a);
      vfprintf (wap, a, ap);
      va_end (ap);
      fclose (wap);
      return 1;
    }
  return 0;
}

int
notalphasort (const void *a, const void *b)
{
  return alphasort (b, a);
}

FILE *
vfopen (const char *mode, const char *path, ...)
{
  char plik[256];
  va_list ap;

  va_start (ap, path);
  vsnprintf (plik, sizeof (plik), path, ap);
  va_end (ap);
  return fopen (plik, mode);
}

/*
Funkcja pisze do logu
*/

int
dologu (int noold, const char *a, ...)
{
  va_list ap;
  FILE *wap;

  if (noold == 1)
    return 0;

  if ((wap = vfopen ("a", "%.100s/wap-query.log", home)))
    {
      va_start (ap, a);
      vfprintf (wap, a, ap);
      va_end (ap);
      fclose (wap);
    }
  return 0;
}
