/*
 * CUPS API test program for CUPS.
 *
 * Copyright 2007-2017 by Apple Inc.
 * Copyright 2007 by Easy Software Products.
 *
 * These coded instructions, statements, and computer programs are the
 * property of Apple Inc. and are protected by Federal copyright
 * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 * which should have been included with this file.  If this file is
 * missing or damaged, see the license at "http://www.cups.org/".
 *
 * This file is subject to the Apple OS-Developed Software exception.
 */

/*
 * Include necessary headers...
 */

#undef _CUPS_NO_DEPRECATED
#include "string-private.h"
#include "cups.h"
#include "ppd.h"
#include <stdlib.h>


/*
 * Local functions...
 */

static int	dests_equal(cups_dest_t *a, cups_dest_t *b);
static int	enum_cb(void *user_data, unsigned flags, cups_dest_t *dest);
static void	show_diffs(cups_dest_t *a, cups_dest_t *b);


/*
 * 'main()' - Main entry.
 */

int					/* O - Exit status */
main(int  argc,				/* I - Number of command-line arguments */
     char *argv[])			/* I - Command-line arguments */
{
  int		status = 0,		/* Exit status */
		i,			/* Looping var */
		num_dests;		/* Number of destinations */
  cups_dest_t	*dests,			/* Destinations */
		*dest,			/* Current destination */
		*named_dest;		/* Current named destination */
  const char	*dest_name,             /* Destination name */
                *dval,                  /* Destination value */
                *ppdfile;		/* PPD file */
  ppd_file_t	*ppd;			/* PPD file data */
  int		num_jobs;		/* Number of jobs for queue */
  cups_job_t	*jobs;			/* Jobs for queue */


  if (argc > 1)
  {
    if (!strcmp(argv[1], "enum"))
    {
      cups_ptype_t	mask = CUPS_PRINTER_LOCAL,
					/* Printer type mask */
			type = CUPS_PRINTER_LOCAL;
					/* Printer type */
      int		msec = 0;	/* Timeout in milliseconds */


      for (i = 2; i < argc; i ++)
        if (isdigit(argv[i][0] & 255) || argv[i][0] == '.')
          msec = (int)(atof(argv[i]) * 1000);
        else if (!_cups_strcasecmp(argv[i], "bw"))
        {
          mask |= CUPS_PRINTER_BW;
          type |= CUPS_PRINTER_BW;
        }
        else if (!_cups_strcasecmp(argv[i], "color"))
        {
          mask |= CUPS_PRINTER_COLOR;
          type |= CUPS_PRINTER_COLOR;
        }
        else if (!_cups_strcasecmp(argv[i], "mono"))
        {
          mask |= CUPS_PRINTER_COLOR;
        }
        else if (!_cups_strcasecmp(argv[i], "duplex"))
        {
          mask |= CUPS_PRINTER_DUPLEX;
          type |= CUPS_PRINTER_DUPLEX;
        }
        else if (!_cups_strcasecmp(argv[i], "simplex"))
        {
          mask |= CUPS_PRINTER_DUPLEX;
        }
        else if (!_cups_strcasecmp(argv[i], "staple"))
        {
          mask |= CUPS_PRINTER_STAPLE;
          type |= CUPS_PRINTER_STAPLE;
        }
        else if (!_cups_strcasecmp(argv[i], "copies"))
        {
          mask |= CUPS_PRINTER_COPIES;
          type |= CUPS_PRINTER_COPIES;
        }
        else if (!_cups_strcasecmp(argv[i], "collate"))
        {
          mask |= CUPS_PRINTER_COLLATE;
          type |= CUPS_PRINTER_COLLATE;
        }
        else if (!_cups_strcasecmp(argv[i], "punch"))
        {
          mask |= CUPS_PRINTER_PUNCH;
          type |= CUPS_PRINTER_PUNCH;
        }
        else if (!_cups_strcasecmp(argv[i], "cover"))
        {
          mask |= CUPS_PRINTER_COVER;
          type |= CUPS_PRINTER_COVER;
        }
        else if (!_cups_strcasecmp(argv[i], "bind"))
        {
          mask |= CUPS_PRINTER_BIND;
          type |= CUPS_PRINTER_BIND;
        }
        else if (!_cups_strcasecmp(argv[i], "sort"))
        {
          mask |= CUPS_PRINTER_SORT;
          type |= CUPS_PRINTER_SORT;
        }
        else if (!_cups_strcasecmp(argv[i], "mfp"))
        {
          mask |= CUPS_PRINTER_MFP;
          type |= CUPS_PRINTER_MFP;
        }
        else if (!_cups_strcasecmp(argv[i], "printer"))
        {
          mask |= CUPS_PRINTER_MFP;
        }
        else if (!_cups_strcasecmp(argv[i], "large"))
        {
          mask |= CUPS_PRINTER_LARGE;
          type |= CUPS_PRINTER_LARGE;
        }
        else if (!_cups_strcasecmp(argv[i], "medium"))
        {
          mask |= CUPS_PRINTER_MEDIUM;
          type |= CUPS_PRINTER_MEDIUM;
        }
        else if (!_cups_strcasecmp(argv[i], "small"))
        {
          mask |= CUPS_PRINTER_SMALL;
          type |= CUPS_PRINTER_SMALL;
        }
        else
          fprintf(stderr, "Unknown argument \"%s\" ignored...\n", argv[i]);

      cupsEnumDests(CUPS_DEST_FLAGS_NONE, msec, NULL, type, mask, enum_cb, NULL);
    }
    else if (!strcmp(argv[1], "password"))
    {
      const char *pass = cupsGetPassword("Password:");
					  /* Password string */

      if (pass)
	printf("Password entered: %s\n", pass);
      else
	puts("No password entered.");
    }
    else if (!strcmp(argv[1], "ppd") && argc == 3)
    {
     /*
      * ./testcups ppd printer
      */

      http_status_t	http_status;	/* Status */
      char		buffer[1024];	/* PPD filename */
      time_t		modtime = 0;	/* Last modified */

      if ((http_status = cupsGetPPD3(CUPS_HTTP_DEFAULT, argv[2], &modtime,
                                     buffer, sizeof(buffer))) != HTTP_STATUS_OK)
        printf("Unable to get PPD: %d (%s)\n", (int)http_status,
               cupsLastErrorString());
      else
        puts(buffer);
    }
    else if (!strcmp(argv[1], "print") && argc == 5)
    {
     /*
      * ./testcups print printer file interval
      */

      int		interval,	/* Interval between writes */
			job_id;		/* Job ID */
      cups_file_t	*fp;		/* Print file */
      char		buffer[16384];	/* Read/write buffer */
      ssize_t		bytes;		/* Bytes read/written */

      if ((fp = cupsFileOpen(argv[3], "r")) == NULL)
      {
	printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno));
	return (1);
      }

      if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[2], "testcups", 0,
				  NULL)) <= 0)
      {
	printf("Unable to create print job on %s: %s\n", argv[1],
	       cupsLastErrorString());
	return (1);
      }

      interval = atoi(argv[4]);

      if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2],
			    CUPS_FORMAT_AUTO, 1) != HTTP_STATUS_CONTINUE)
      {
	puts("Unable to start document!");
	return (1);
      }

      while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
      {
	printf("Writing %d bytes...\n", (int)bytes);

	if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, (size_t)bytes) != HTTP_STATUS_CONTINUE)
	{
	  puts("Unable to write bytes!");
	  return (1);
	}

        if (interval > 0)
	  sleep((unsigned)interval);
      }

      cupsFileClose(fp);

      if (cupsFinishDocument(CUPS_HTTP_DEFAULT,
                             argv[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
      {
	puts("Unable to finish document!");
	return (1);
      }
    }
    else
    {
      puts("Usage:");
      puts("");
      puts("Run basic unit tests:");
      puts("");
      puts("    ./testcups");
      puts("");
      puts("Enumerate printers (for N seconds, -1 for indefinitely):");
      puts("");
      puts("    ./testcups enum [seconds]");
      puts("");
      puts("Ask for a password:");
      puts("");
      puts("    ./testcups password");
      puts("");
      puts("Get the PPD file:");
      puts("");
      puts("    ./testcups ppd printer");
      puts("");
      puts("Print a file (interval controls delay between buffers in seconds):");
      puts("");
      puts("    ./testcups print printer file interval");
      return (1);
    }

    return (0);
  }

 /*
  * cupsGetDests()
  */

  fputs("cupsGetDests: ", stdout);
  fflush(stdout);

  num_dests = cupsGetDests(&dests);

  if (num_dests == 0)
  {
    puts("FAIL");
    return (1);
  }
  else
  {
    printf("PASS (%d dests)\n", num_dests);

    for (i = num_dests, dest = dests; i > 0; i --, dest ++)
    {
      printf("    %s", dest->name);

      if (dest->instance)
        printf("    /%s", dest->instance);

      if (dest->is_default)
        puts(" ***DEFAULT***");
      else
        putchar('\n');
    }
  }

 /*
  * cupsGetDest(NULL)
  */

  fputs("cupsGetDest(NULL): ", stdout);
  fflush(stdout);

  if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL)
  {
    for (i = num_dests, dest = dests; i > 0; i --, dest ++)
      if (dest->is_default)
        break;

    if (i)
    {
      status = 1;
      puts("FAIL");
    }
    else
      puts("PASS (no default)");

    dest = NULL;
  }
  else
    printf("PASS (%s)\n", dest->name);

 /*
  * cupsGetNamedDest(NULL, NULL, NULL)
  */

  fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout);
  fflush(stdout);

  if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL ||
      !dests_equal(dest, named_dest))
  {
    if (!dest)
      puts("PASS (no default)");
    else if (named_dest)
    {
      puts("FAIL (different values)");
      show_diffs(dest, named_dest);
      status = 1;
    }
    else
    {
      puts("FAIL (no default)");
      status = 1;
    }
  }
  else
    printf("PASS (%s)\n", named_dest->name);

  if (named_dest)
    cupsFreeDests(1, named_dest);

 /*
  * cupsGetDest(printer)
  */

  for (i = 0, dest_name = NULL; i < num_dests; i ++)
  {
    if ((dval = cupsGetOption("printer-is-temporary", dests[i].num_options, dest[i].options)) != NULL && !strcmp(dval, "false"))
    {
      dest_name = dests[i].name;
      break;
    }
  }

  printf("cupsGetDest(\"%s\"): ", dest_name ? dest_name : "(null)");
  fflush(stdout);

  if ((dest = cupsGetDest(dest_name, NULL, num_dests, dests)) == NULL)
  {
    puts("FAIL");
    return (1);
  }
  else
    puts("PASS");

 /*
  * cupsGetNamedDest(NULL, printer, instance)
  */

  printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name,
         dest->instance ? dest->instance : "(null)");
  fflush(stdout);

  if ((named_dest = cupsGetNamedDest(NULL, dest->name, dest->instance)) == NULL ||
      !dests_equal(dest, named_dest))
  {
    if (named_dest)
    {
      puts("FAIL (different values)");
      show_diffs(dest, named_dest);
    }
    else
      puts("FAIL (no destination)");


    status = 1;
  }
  else
    puts("PASS");

  if (named_dest)
    cupsFreeDests(1, named_dest);

 /*
  * cupsPrintFile()
  */

  fputs("cupsPrintFile: ", stdout);
  fflush(stdout);

  if (cupsPrintFile(dest->name, "../test/testfile.pdf", "Test Page",
                    dest->num_options, dest->options) <= 0)
  {
    printf("FAIL (%s)\n", cupsLastErrorString());
    return (1);
  }
  else
    puts("PASS");

 /*
  * cupsGetPPD(printer)
  */

  fputs("cupsGetPPD: ", stdout);
  fflush(stdout);

  if ((ppdfile = cupsGetPPD(dest->name)) == NULL)
  {
    puts("FAIL");
  }
  else
  {
    puts("PASS");

   /*
    * ppdOpenFile()
    */

    fputs("ppdOpenFile: ", stdout);
    fflush(stdout);

    if ((ppd = ppdOpenFile(ppdfile)) == NULL)
    {
      puts("FAIL");
      return (1);
    }
    else
      puts("PASS");

    ppdClose(ppd);
    unlink(ppdfile);
  }

 /*
  * cupsGetJobs()
  */

  fputs("cupsGetJobs: ", stdout);
  fflush(stdout);

  num_jobs = cupsGetJobs(&jobs, NULL, 0, -1);

  if (num_jobs == 0)
  {
    puts("FAIL");
    return (1);
  }
  else
    puts("PASS");

  cupsFreeJobs(num_jobs, jobs);
  cupsFreeDests(num_dests, dests);

  return (status);
}


/*
 * 'dests_equal()' - Determine whether two destinations are equal.
 */

static int				/* O - 1 if equal, 0 if not equal */
dests_equal(cups_dest_t *a,		/* I - First destination */
            cups_dest_t *b)		/* I - Second destination */
{
  int		i;			/* Looping var */
  cups_option_t	*aoption;		/* Current option */
  const char	*bval;			/* Option value */


  if (a == b)
    return (1);

  if (!a || !b)
    return (0);

  if (_cups_strcasecmp(a->name, b->name) ||
      (a->instance && !b->instance) ||
      (!a->instance && b->instance) ||
      (a->instance && _cups_strcasecmp(a->instance, b->instance)) ||
      a->num_options != b->num_options)
    return (0);

  for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
    if ((bval = cupsGetOption(aoption->name, b->num_options,
                              b->options)) == NULL ||
        strcmp(aoption->value, bval))
      return (0);

  return (1);
}


/*
 * 'enum_cb()' - Report additions and removals.
 */

static int				/* O - 1 to continue, 0 to stop */
enum_cb(void        *user_data,		/* I - User data (unused) */
        unsigned    flags,		/* I - Destination flags */
        cups_dest_t *dest)		/* I - Destination */
{
  int		i;			/* Looping var */
  cups_option_t	*option;		/* Current option */


  (void)user_data;

  if (flags & CUPS_DEST_FLAGS_REMOVED)
    printf("Removed '%s':\n", dest->name);
  else
    printf("Added '%s':\n", dest->name);

  for (i = dest->num_options, option = dest->options; i > 0; i --, option ++)
    printf("    %s=\"%s\"\n", option->name, option->value);

  putchar('\n');

  return (1);
}


/*
 * 'show_diffs()' - Show differences between two destinations.
 */

static void
show_diffs(cups_dest_t *a,		/* I - First destination */
           cups_dest_t *b)		/* I - Second destination */
{
  int		i;			/* Looping var */
  cups_option_t	*aoption;		/* Current option */
  cups_option_t	*boption;		/* Current option */
  const char	*bval;			/* Option value */


  if (!a || !b)
    return;

  puts("    Item                  cupsGetDest               cupsGetNamedDest");
  puts("    --------------------  ------------------------  ------------------------");

  if (_cups_strcasecmp(a->name, b->name))
    printf("    name                  %-24.24s  %-24.24s\n", a->name, b->name);

  if ((a->instance && !b->instance) ||
      (!a->instance && b->instance) ||
      (a->instance && _cups_strcasecmp(a->instance, b->instance)))
    printf("    instance              %-24.24s  %-24.24s\n",
           a->instance ? a->instance : "(null)",
	   b->instance ? b->instance : "(null)");

  if (a->num_options != b->num_options)
    printf("    num_options           %-24d  %-24d\n", a->num_options,
           b->num_options);

  for (i = a->num_options, aoption = a->options; i > 0; i --, aoption ++)
    if ((bval = cupsGetOption(aoption->name, b->num_options,
                              b->options)) == NULL ||
        strcmp(aoption->value, bval))
      printf("    %-20.20s  %-24.24s  %-24.24s\n", aoption->name,
             aoption->value, bval ? bval : "(null)");

  for (i = b->num_options, boption = b->options; i > 0; i --, boption ++)
    if (!cupsGetOption(boption->name, a->num_options, a->options))
      printf("    %-20.20s  %-24.24s  %-24.24s\n", boption->name,
             boption->value, "(null)");
}
