#include <stdio.h>
#include "server.h"

/*
 * Ugh! This routine is too gross!
 *
 * ERRORS:
 *
 * APP_BADLICSTRUCT: FATAL
 * There was a license block without any info. This can't happen. Heh.
 *
 * APP_LICWITHNOPOOLS: FATAL
 * A license was created without any pools.
 */
Trap processLicenses(block, firstlic)
     MasterBlock *block;
     License **firstlic;
{
  License *firstLic = NULL, *currentLic, *lastLic;
  Pool *currentPool, *lastPool;

  *firstlic = NULL;
  while (1)
    {
      while (strcmp(PACKAGE, Parse_CurrentBlockType(block)))
	if (Parse_NextBlock(block))
	  {
	    Error_Pop();
	    return OK;
	  }

      if (Parse_GetCurrentData(block, PACKDATA, (caddr_t *)&currentLic, 0))
	Return(APP_BADLICSTRUCT, NULL);

      if (firstLic == NULL)
	{
	  firstLic = currentLic;
	  *firstlic = currentLic;
	}
      else
	lastLic->next = currentLic;

      currentLic->numPools = 0;

      if (Parse_Subblock(block))
	Return(APP_LICWITHNOPOOLS, NULL);

      do {
	if (Parse_GetCurrentData(block, POOLDATA, (caddr_t *)&currentPool, 0))
	  Return(APP_LICWITHNOPOOLS, NULL);

	currentPool->pb = Parse_CurrentBlock(block);
	currentPool->free = currentPool->licenses;

	if (currentLic->firstPool == NULL)
	  {
	    currentLic->firstPool = currentPool;
	    lastPool = currentPool;
	  }
	else
	  lastPool->next = currentPool;

	currentPool->license = currentLic;

	lastPool = currentPool;
	currentLic->numPools++;
      } while (!Parse_NextBlock(block));
      Error_Pop();

      Parse_UpBlock(block);
      lastLic = currentLic;

      if (Parse_NextBlock(block))
	{
	  Error_Pop();
	  return OK;
	}
    }
}

ReleaseLicenses(c)
     Context *c;
{
  c->what->free += c->licensesHeld;
  c->licensesHeld = 0;
}

OldPool *MakeOldPoolFromCurrent(s)
     srvinfo *s;
{
  License *l;
  Pool *p;
  OldPool *op;
  int i = 0;

  op = (OldPool *)malloc(s->totalPools * sizeof(OldPool));
  if (op == NULL)
    return NULL;

  for (l = s->firstLicense; l != NULL; l = l->next)
    for (p = l->firstPool; p != NULL; p = p->next)
      {
	op[i].active = p->active;
	op[i].free = p->free;
	i++;
      }

  return op;
}

PutPoolToPacket(Pout, s, op)
     P0Block *Pout;
     srvinfo *s;
     OldPool *op;
{
  int i;

  for (i = 0; i < s->totalPools; i++)
    {
      P0_PutCard16(Pout, op[i].active);
      P0_PutCard16(Pout, op[i].free);
    }
}

OldPool *GetPoolFromPacket(Pin, s)
     P0Packet *Pin;
     srvinfo *s;
{
  OldPool *op;
  int i;

  op = (OldPool *)malloc(s->totalPools * sizeof(OldPool));
  if (op == NULL)
    return NULL;

  for (i = 0; i < s->totalPools; i++)
    {
      P0_GetCard16(Pin, &op[i].active);
      P0_GetCard16(Pin, &op[i].free);
    }

  return op;
}
