/*
 * Destination option/media support for CUPS.
 *
 * Copyright 2012-2017 by Apple Inc.
 *
 * 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...
 */

#include "cups-private.h"


/*
 * Local constants...
 */

#define _CUPS_MEDIA_READY_TTL	30	/* Life of xxx-ready values */


/*
 * Local functions...
 */

static void		cups_add_dconstres(cups_array_t *a, ipp_t *collection);
static int		cups_compare_dconstres(_cups_dconstres_t *a,
			                       _cups_dconstres_t *b);
static int		cups_compare_media_db(_cups_media_db_t *a,
			                      _cups_media_db_t *b);
static _cups_media_db_t	*cups_copy_media_db(_cups_media_db_t *mdb);
static void		cups_create_cached(http_t *http, cups_dinfo_t *dinfo,
			                   unsigned flags);
static void		cups_create_constraints(cups_dinfo_t *dinfo);
static void		cups_create_defaults(cups_dinfo_t *dinfo);
static void		cups_create_media_db(cups_dinfo_t *dinfo,
			                     unsigned flags);
static void		cups_free_media_db(_cups_media_db_t *mdb);
static int		cups_get_media_db(http_t *http, cups_dinfo_t *dinfo,
			                  pwg_media_t *pwg, unsigned flags,
			                  cups_size_t *size);
static int		cups_is_close_media_db(_cups_media_db_t *a,
			                       _cups_media_db_t *b);
static cups_array_t	*cups_test_constraints(cups_dinfo_t *dinfo,
					       const char *new_option,
					       const char *new_value,
					       int num_options,
					       cups_option_t *options,
					       int *num_conflicts,
					       cups_option_t **conflicts);
static void		cups_update_ready(http_t *http, cups_dinfo_t *dinfo);


/*
 * 'cupsCheckDestSupported()' - Check that the option and value are supported
 *                              by the destination.
 *
 * Returns 1 if supported, 0 otherwise.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 if supported, 0 otherwise */
cupsCheckDestSupported(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option,		/* I - Option */
    const char   *value)		/* I - Value or @code NULL@ */
{
  int			i;		/* Looping var */
  char			temp[1024];	/* Temporary string */
  int			int_value;	/* Integer value */
  int			xres_value,	/* Horizontal resolution */
			yres_value;	/* Vertical resolution */
  ipp_res_t		units_value;	/* Resolution units */
  ipp_attribute_t	*attr;		/* Attribute */
  _ipp_value_t		*attrval;	/* Current attribute value */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
    return (0);

 /*
  * Lookup the attribute...
  */

  if (strstr(option, "-supported"))
    attr = ippFindAttribute(dinfo->attrs, option, IPP_TAG_ZERO);
  else
  {
    snprintf(temp, sizeof(temp), "%s-supported", option);
    attr = ippFindAttribute(dinfo->attrs, temp, IPP_TAG_ZERO);
  }

  if (!attr)
    return (0);

  if (!value)
    return (1);

/*
  * Compare values...
  */

  if (!strcmp(option, "media") && !strncmp(value, "custom_", 7))
  {
   /*
    * Check range of custom media sizes...
    */

    pwg_media_t	*pwg;		/* Current PWG media size info */
    int			min_width,	/* Minimum width */
			min_length,	/* Minimum length */
			max_width,	/* Maximum width */
			max_length;	/* Maximum length */

   /*
    * Get the minimum and maximum size...
    */

    min_width = min_length = INT_MAX;
    max_width = max_length = 0;

    for (i = attr->num_values, attrval = attr->values;
	 i > 0;
	 i --, attrval ++)
    {
      if (!strncmp(attrval->string.text, "custom_min_", 11) &&
          (pwg = pwgMediaForPWG(attrval->string.text)) != NULL)
      {
        min_width  = pwg->width;
        min_length = pwg->length;
      }
      else if (!strncmp(attrval->string.text, "custom_max_", 11) &&
	       (pwg = pwgMediaForPWG(attrval->string.text)) != NULL)
      {
        max_width  = pwg->width;
        max_length = pwg->length;
      }
    }

   /*
    * Check the range...
    */

    if (min_width < INT_MAX && max_width > 0 &&
        (pwg = pwgMediaForPWG(value)) != NULL &&
        pwg->width >= min_width && pwg->width <= max_width &&
        pwg->length >= min_length && pwg->length <= max_length)
      return (1);
  }
  else
  {
   /*
    * Check literal values...
    */

    switch (attr->value_tag)
    {
      case IPP_TAG_INTEGER :
      case IPP_TAG_ENUM :
          int_value = atoi(value);

          for (i = 0; i < attr->num_values; i ++)
            if (attr->values[i].integer == int_value)
              return (1);
          break;

      case IPP_TAG_BOOLEAN :
          return (attr->values[0].boolean);

      case IPP_TAG_RANGE :
          int_value = atoi(value);

          for (i = 0; i < attr->num_values; i ++)
            if (int_value >= attr->values[i].range.lower &&
                int_value <= attr->values[i].range.upper)
              return (1);
          break;

      case IPP_TAG_RESOLUTION :
          if (sscanf(value, "%dx%d%15s", &xres_value, &yres_value, temp) != 3)
          {
            if (sscanf(value, "%d%15s", &xres_value, temp) != 2)
              return (0);

            yres_value = xres_value;
          }

          if (!strcmp(temp, "dpi"))
            units_value = IPP_RES_PER_INCH;
          else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm"))
            units_value = IPP_RES_PER_CM;
          else
            return (0);

          for (i = attr->num_values, attrval = attr->values;
               i > 0;
               i --, attrval ++)
          {
            if (attrval->resolution.xres == xres_value &&
                attrval->resolution.yres == yres_value &&
                attrval->resolution.units == units_value)
              return (1);
          }
          break;

      case IPP_TAG_TEXT :
      case IPP_TAG_NAME :
      case IPP_TAG_KEYWORD :
      case IPP_TAG_CHARSET :
      case IPP_TAG_URI :
      case IPP_TAG_URISCHEME :
      case IPP_TAG_MIMETYPE :
      case IPP_TAG_LANGUAGE :
      case IPP_TAG_TEXTLANG :
      case IPP_TAG_NAMELANG :
          for (i = 0; i < attr->num_values; i ++)
            if (!strcmp(attr->values[i].string.text, value))
              return (1);
          break;

      default :
          break;
    }
  }

 /*
  * If we get there the option+value is not supported...
  */

  return (0);
}


/*
 * 'cupsCopyDestConflicts()' - Get conflicts and resolutions for a new
 *                             option/value pair.
 *
 * "num_options" and "options" represent the currently selected options by the
 * user.  "new_option" and "new_value" are the setting the user has just
 * changed.
 *
 * Returns 1 if there is a conflict, 0 if there are no conflicts, and -1 if
 * there was an unrecoverable error such as a resolver loop.
 *
 * If "num_conflicts" and "conflicts" are not @code NULL@, they are set to
 * contain the list of conflicting option/value pairs.  Similarly, if
 * "num_resolved" and "resolved" are not @code NULL@ they will be set to the
 * list of changes needed to resolve the conflict.
 *
 * If cupsCopyDestConflicts returns 1 but "num_resolved" and "resolved" are set
 * to 0 and @code NULL@, respectively, then the conflict cannot be resolved.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 if there is a conflict, 0 if none, -1 on error */
cupsCopyDestConflicts(
    http_t        *http,		/* I - Connection to destination */
    cups_dest_t   *dest,		/* I - Destination */
    cups_dinfo_t  *dinfo,		/* I - Destination information */
    int           num_options,		/* I - Number of current options */
    cups_option_t *options,		/* I - Current options */
    const char    *new_option,		/* I - New option */
    const char    *new_value,		/* I - New value */
    int           *num_conflicts,	/* O - Number of conflicting options */
    cups_option_t **conflicts,		/* O - Conflicting options */
    int           *num_resolved,	/* O - Number of options to resolve */
    cups_option_t **resolved)		/* O - Resolved options */
{
  int		i,			/* Looping var */
		have_conflicts = 0,	/* Do we have conflicts? */
		changed,		/* Did we change something? */
		tries,			/* Number of tries for resolution */
		num_myconf = 0,		/* My number of conflicting options */
		num_myres = 0;		/* My number of resolved options */
  cups_option_t	*myconf = NULL,		/* My conflicting options */
		*myres = NULL,		/* My resolved options */
		*myoption,		/* My current option */
		*option;		/* Current option */
  cups_array_t	*active = NULL,		/* Active conflicts */
		*pass = NULL,		/* Resolvers for this pass */
		*resolvers = NULL,	/* Resolvers we have used */
		*test;			/* Test array for conflicts */
  _cups_dconstres_t *c,			/* Current constraint */
		*r;			/* Current resolver */
  ipp_attribute_t *attr;		/* Current attribute */
  char		value[2048];		/* Current attribute value as string */
  const char	*myvalue;		/* Current value of an option */


 /*
  * Clear returned values...
  */

  if (num_conflicts)
    *num_conflicts = 0;

  if (conflicts)
    *conflicts = NULL;

  if (num_resolved)
    *num_resolved = 0;

  if (resolved)
    *resolved = NULL;

 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo ||
      (num_conflicts != NULL) != (conflicts != NULL) ||
      (num_resolved != NULL) != (resolved != NULL))
    return (0);

 /*
  * Load constraints as needed...
  */

  if (!dinfo->constraints)
    cups_create_constraints(dinfo);

  if (cupsArrayCount(dinfo->constraints) == 0)
    return (0);

  if (!dinfo->num_defaults)
    cups_create_defaults(dinfo);

 /*
  * If we are resolving, create a shadow array...
  */

  if (num_resolved)
  {
    for (i = num_options, option = options; i > 0; i --, option ++)
      num_myres = cupsAddOption(option->name, option->value, num_myres, &myres);

    if (new_option && new_value)
      num_myres = cupsAddOption(new_option, new_value, num_myres, &myres);
  }
  else
  {
    num_myres = num_options;
    myres     = options;
  }

 /*
  * Check for any conflicts...
  */

  if (num_resolved)
    pass = cupsArrayNew((cups_array_func_t)cups_compare_dconstres, NULL);

  for (tries = 0; tries < 100; tries ++)
  {
   /*
    * Check for any conflicts...
    */

    if (num_conflicts || num_resolved)
    {
      cupsFreeOptions(num_myconf, myconf);

      num_myconf = 0;
      myconf     = NULL;
      active     = cups_test_constraints(dinfo, new_option, new_value,
                                         num_myres, myres, &num_myconf,
                                         &myconf);
    }
    else
      active = cups_test_constraints(dinfo, new_option, new_value, num_myres,
				     myres, NULL, NULL);

    have_conflicts = (active != NULL);

    if (!active || !num_resolved)
      break;				/* All done */

   /*
    * Scan the constraints that were triggered to apply resolvers...
    */

    if (!resolvers)
      resolvers = cupsArrayNew((cups_array_func_t)cups_compare_dconstres, NULL);

    for (c = (_cups_dconstres_t *)cupsArrayFirst(active), changed = 0;
         c;
         c = (_cups_dconstres_t *)cupsArrayNext(active))
    {
      if (cupsArrayFind(pass, c))
        continue;			/* Already applied this resolver... */

      if (cupsArrayFind(resolvers, c))
      {
        DEBUG_printf(("1cupsCopyDestConflicts: Resolver loop with %s.",
                      c->name));
        have_conflicts = -1;
        goto cleanup;
      }

      if ((r = cupsArrayFind(dinfo->resolvers, c)) == NULL)
      {
        DEBUG_printf(("1cupsCopyDestConflicts: Resolver %s not found.",
                      c->name));
        have_conflicts = -1;
        goto cleanup;
      }

     /*
      * Add the options from the resolver...
      */

      cupsArrayAdd(pass, r);
      cupsArrayAdd(resolvers, r);

      for (attr = ippFirstAttribute(r->collection);
           attr;
           attr = ippNextAttribute(r->collection))
      {
        if (new_option && !strcmp(attr->name, new_option))
          continue;			/* Ignore this if we just changed it */

        if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value))
          continue;			/* Ignore if the value is too long */

        if ((test = cups_test_constraints(dinfo, attr->name, value, num_myres,
                                          myres, NULL, NULL)) == NULL)
        {
         /*
          * That worked, flag it...
          */

          changed = 1;
        }
        else
          cupsArrayDelete(test);

       /*
	* Add the option/value from the resolver regardless of whether it
	* worked; this makes sure that we can cascade several changes to
	* make things resolve...
	*/

	num_myres = cupsAddOption(attr->name, value, num_myres, &myres);
      }
    }

    if (!changed)
    {
      DEBUG_puts("1cupsCopyDestConflicts: Unable to resolve constraints.");
      have_conflicts = -1;
      goto cleanup;
    }

    cupsArrayClear(pass);

    cupsArrayDelete(active);
    active = NULL;
  }

  if (tries >= 100)
  {
    DEBUG_puts("1cupsCopyDestConflicts: Unable to resolve after 100 tries.");
    have_conflicts = -1;
    goto cleanup;
  }

 /*
  * Copy resolved options as needed...
  */

  if (num_resolved)
  {
    for (i = num_myres, myoption = myres; i > 0; i --, myoption ++)
    {
      if ((myvalue = cupsGetOption(myoption->name, num_options,
                                   options)) == NULL ||
          strcmp(myvalue, myoption->value))
      {
        if (new_option && !strcmp(new_option, myoption->name) &&
            new_value && !strcmp(new_value, myoption->value))
          continue;

        *num_resolved = cupsAddOption(myoption->name, myoption->value,
                                      *num_resolved, resolved);
      }
    }
  }

 /*
  * Clean up...
  */

  cleanup:

  cupsArrayDelete(active);
  cupsArrayDelete(pass);
  cupsArrayDelete(resolvers);

  if (num_resolved)
  {
   /*
    * Free shadow copy of options...
    */

    cupsFreeOptions(num_myres, myres);
  }

  if (num_conflicts)
  {
   /*
    * Return conflicting options to caller...
    */

    *num_conflicts = num_myconf;
    *conflicts     = myconf;
  }
  else
  {
   /*
    * Free conflicting options...
    */

    cupsFreeOptions(num_myconf, myconf);
  }

  return (have_conflicts);
}


/*
 * 'cupsCopyDestInfo()' - Get the supported values/capabilities for the
 *                        destination.
 *
 * The caller is responsible for calling @link cupsFreeDestInfo@ on the return
 * value. @code NULL@ is returned on error.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

cups_dinfo_t *				/* O - Destination information */
cupsCopyDestInfo(
    http_t      *http,			/* I - Connection to destination */
    cups_dest_t *dest)			/* I - Destination */
{
  cups_dinfo_t	*dinfo;			/* Destination information */
  ipp_t		*request,		/* Get-Printer-Attributes request */
		*response;		/* Supported attributes */
  int		tries,			/* Number of tries so far */
		delay,			/* Current retry delay */
		prev_delay;		/* Next retry delay */
  const char	*uri;			/* Printer URI */
  char		resource[1024];		/* Resource path */
  int		version;		/* IPP version */
  ipp_status_t	status;			/* Status of request */
  static const char * const requested_attrs[] =
  {					/* Requested attributes */
    "job-template",
    "media-col-database",
    "printer-description"
  };


  DEBUG_printf(("cupsCopyDestSupported(http=%p, dest=%p(%s))", (void *)http, (void *)dest, dest ? dest->name : ""));

 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest)
    return (NULL);

 /*
  * Get the printer URI and resource path...
  */

  if ((uri = _cupsGetDestResource(dest, resource, sizeof(resource))) == NULL)
    return (NULL);

 /*
  * Get the supported attributes...
  */

  delay      = 1;
  prev_delay = 1;
  tries      = 0;
  version    = 20;

  do
  {
   /*
    * Send a Get-Printer-Attributes request...
    */

    request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
		 uri);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                 "requesting-user-name", NULL, cupsUser());
    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
		  "requested-attributes",
		  (int)(sizeof(requested_attrs) / sizeof(requested_attrs[0])),
		  NULL, requested_attrs);
    response = cupsDoRequest(http, request, resource);
    status   = cupsLastError();

    if (status > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED)
    {
      DEBUG_printf(("cupsCopyDestSupported: Get-Printer-Attributes for '%s' "
		    "returned %s (%s)", dest->name, ippErrorString(status),
		    cupsLastErrorString()));

      ippDelete(response);
      response = NULL;

      if (status == IPP_STATUS_ERROR_VERSION_NOT_SUPPORTED && version > 11)
        version = 11;
      else if (status == IPP_STATUS_ERROR_BUSY)
      {
        sleep((unsigned)delay);

        delay = _cupsNextDelay(delay, &prev_delay);
      }
      else
        return (NULL);
    }

    tries ++;
  }
  while (!response && tries < 10);

  if (!response)
    return (NULL);

 /*
  * Allocate a cups_dinfo_t structure and return it...
  */

  if ((dinfo = calloc(1, sizeof(cups_dinfo_t))) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(errno), 0);
    ippDelete(response);
    return (NULL);
  }

  dinfo->version  = version;
  dinfo->uri      = uri;
  dinfo->resource = _cupsStrAlloc(resource);
  dinfo->attrs    = response;

  return (dinfo);
}


/*
 * 'cupsFindDestDefault()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestDefault(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  snprintf(name, sizeof(name), "%s-default", option);
  return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFindDestReady()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestReady(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  cups_update_ready(http, dinfo);

  snprintf(name, sizeof(name), "%s-ready", option);
  return (ippFindAttribute(dinfo->ready_attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFindDestSupported()' - Find the default value(s) for the given option.
 *
 * The returned value is an IPP attribute. Use the @code ippGetBoolean@,
 * @code ippGetCollection@, @code ippGetCount@, @code ippGetDate@,
 * @code ippGetInteger@, @code ippGetOctetString@, @code ippGetRange@,
 * @code ippGetResolution@, @code ippGetString@, and @code ippGetValueTag@
 * functions to inspect the default value(s) as needed.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

ipp_attribute_t	*			/* O - Default attribute or @code NULL@ for none */
cupsFindDestSupported(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *option)		/* I - Option/attribute name */
{
  char	name[IPP_MAX_NAME];		/* Attribute name */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo || !option)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (NULL);
  }

 /*
  * Find and return the attribute...
  */

  snprintf(name, sizeof(name), "%s-supported", option);
  return (ippFindAttribute(dinfo->attrs, name, IPP_TAG_ZERO));
}


/*
 * 'cupsFreeDestInfo()' - Free destination information obtained using
 *                        @link cupsCopyDestInfo@.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

void
cupsFreeDestInfo(cups_dinfo_t *dinfo)	/* I - Destination information */
{
 /*
  * Range check input...
  */

  if (!dinfo)
    return;

 /*
  * Free memory and return...
  */

  _cupsStrFree(dinfo->resource);

  cupsArrayDelete(dinfo->constraints);
  cupsArrayDelete(dinfo->resolvers);

  cupsArrayDelete(dinfo->localizations);

  cupsArrayDelete(dinfo->media_db);

  cupsArrayDelete(dinfo->cached_db);

  ippDelete(dinfo->ready_attrs);
  cupsArrayDelete(dinfo->ready_db);

  ippDelete(dinfo->attrs);

  free(dinfo);
}


/*
 * 'cupsGetDestMediaByIndex()' - Get a media name, dimension, and margins for a
 *                               specific size.
 *
 * The @code flags@ parameter determines which set of media are indexed.  For
 * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will get the Nth
 * borderless size supported by the printer.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - 1 on success, 0 on failure */
cupsGetDestMediaByIndex(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    int          n,			/* I - Media size number (0-based) */
    unsigned     flags,			/* I - Media flags */
    cups_size_t  *size)			/* O - Media size information */
{
  _cups_media_db_t	*nsize;		/* Size for N */
  pwg_media_t		*pwg;		/* PWG media name for size */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || n < 0 || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Load media list as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
    cups_update_ready(http, dinfo);

  if (!dinfo->cached_db || dinfo->cached_flags != flags)
    cups_create_cached(http, dinfo, flags);

 /*
  * Copy the size over and return...
  */

  if ((nsize = (_cups_media_db_t *)cupsArrayIndex(dinfo->cached_db, n)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  if (nsize->size_name)
    strlcpy(size->media, nsize->size_name, sizeof(size->media));
  else if (nsize->key)
    strlcpy(size->media, nsize->key, sizeof(size->media));
  else if ((pwg = pwgMediaForSize(nsize->width, nsize->length)) != NULL)
    strlcpy(size->media, pwg->pwg, sizeof(size->media));
  else
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  size->width  = nsize->width;
  size->length = nsize->length;
  size->bottom = nsize->bottom;
  size->left   = nsize->left;
  size->right  = nsize->right;
  size->top    = nsize->top;

  return (1);
}


/*
 * 'cupsGetDestMediaByName()' - Get media names, dimensions, and margins.
 *
 * The "media" string is a PWG media name.  "Flags" provides some matching
 * guidance (multiple flags can be combined):
 *
 * CUPS_MEDIA_FLAGS_DEFAULT    = find the closest size supported by the printer,
 * CUPS_MEDIA_FLAGS_BORDERLESS = find a borderless size,
 * CUPS_MEDIA_FLAGS_DUPLEX     = find a size compatible with 2-sided printing,
 * CUPS_MEDIA_FLAGS_EXACT      = find an exact match for the size, and
 * CUPS_MEDIA_FLAGS_READY      = if the printer supports media sensing, find the
 *                               size amongst the "ready" media.
 *
 * The matching result (if any) is returned in the "cups_size_t" structure.
 *
 * Returns 1 when there is a match and 0 if there is not a match.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 on match, 0 on failure */
cupsGetDestMediaByName(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    const char   *media,		/* I - Media name */
    unsigned     flags,			/* I - Media matching flags */
    cups_size_t  *size)			/* O - Media size information */
{
  pwg_media_t		*pwg;		/* PWG media info */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || !media || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Lookup the media size name...
  */

  if ((pwg = pwgMediaForPWG(media)) == NULL)
    if ((pwg = pwgMediaForLegacy(media)) == NULL)
    {
      DEBUG_printf(("1cupsGetDestMediaByName: Unknown size '%s'.", media));
      _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unknown media size name."), 1);
      return (0);
    }

 /*
  * Lookup the size...
  */

  return (cups_get_media_db(http, dinfo, pwg, flags, size));
}


/*
 * 'cupsGetDestMediaBySize()' - Get media names, dimensions, and margins.
 *
 * "Width" and "length" are the dimensions in hundredths of millimeters.
 * "Flags" provides some matching guidance (multiple flags can be combined):
 *
 * CUPS_MEDIA_FLAGS_DEFAULT    = find the closest size supported by the printer,
 * CUPS_MEDIA_FLAGS_BORDERLESS = find a borderless size,
 * CUPS_MEDIA_FLAGS_DUPLEX     = find a size compatible with 2-sided printing,
 * CUPS_MEDIA_FLAGS_EXACT      = find an exact match for the size, and
 * CUPS_MEDIA_FLAGS_READY      = if the printer supports media sensing, find the
 *                               size amongst the "ready" media.
 *
 * The matching result (if any) is returned in the "cups_size_t" structure.
 *
 * Returns 1 when there is a match and 0 if there is not a match.
 *
 * @since CUPS 1.6/macOS 10.8@
 */

int					/* O - 1 on match, 0 on failure */
cupsGetDestMediaBySize(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    int         width,			/* I - Media width in hundredths of
					 *     of millimeters */
    int         length,			/* I - Media length in hundredths of
					 *     of millimeters */
    unsigned     flags,			/* I - Media matching flags */
    cups_size_t  *size)			/* O - Media size information */
{
  pwg_media_t		*pwg;		/* PWG media info */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || width <= 0 || length <= 0 || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Lookup the media size name...
  */

  if ((pwg = pwgMediaForSize(width, length)) == NULL)
  {
    DEBUG_printf(("1cupsGetDestMediaBySize: Invalid size %dx%d.", width,
                  length));
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid media size."), 1);
    return (0);
  }

 /*
  * Lookup the size...
  */

  return (cups_get_media_db(http, dinfo, pwg, flags, size));
}


/*
 * 'cupsGetDestMediaCount()' - Get the number of sizes supported by a
 *                             destination.
 *
 * The @code flags@ parameter determines the set of media sizes that are
 * counted.  For example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return
 * the number of borderless sizes.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - Number of sizes */
cupsGetDestMediaCount(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags)			/* I - Media flags */
{
 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (!http || !dest || !dinfo)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Load media list as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
    cups_update_ready(http, dinfo);

  if (!dinfo->cached_db || dinfo->cached_flags != flags)
    cups_create_cached(http, dinfo, flags);

  return (cupsArrayCount(dinfo->cached_db));
}


/*
 * 'cupsGetDestMediaDefault()' - Get the default size for a destination.
 *
 * The @code flags@ parameter determines which default size is returned.  For
 * example, passing @code CUPS_MEDIA_FLAGS_BORDERLESS@ will return the default
 * borderless size, typically US Letter or A4, but sometimes 4x6 photo media.
 *
 * @since CUPS 1.7/macOS 10.9@
 */

int					/* O - 1 on success, 0 on failure */
cupsGetDestMediaDefault(
    http_t       *http,			/* I - Connection to destination */
    cups_dest_t  *dest,			/* I - Destination */
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags,			/* I - Media flags */
    cups_size_t  *size)			/* O - Media size information */
{
  const char	*media;			/* Default media size */


 /*
  * Get the default connection as needed...
  */

  if (!http)
    http = _cupsConnect();

 /*
  * Range check input...
  */

  if (size)
    memset(size, 0, sizeof(cups_size_t));

  if (!http || !dest || !dinfo || !size)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Get the default media size, if any...
  */

  if ((media = cupsGetOption("media", dest->num_options,
                             dest->options)) == NULL)
    media = "na_letter_8.5x11in";

  if (cupsGetDestMediaByName(http, dest, dinfo, media, flags, size))
    return (1);

  if (strcmp(media, "na_letter_8.5x11in") &&
      cupsGetDestMediaByName(http, dest, dinfo, "iso_a4_210x297mm", flags,
                             size))
    return (1);

  if (strcmp(media, "iso_a4_210x297mm") &&
      cupsGetDestMediaByName(http, dest, dinfo, "na_letter_8.5x11in", flags,
                             size))
    return (1);

  if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) &&
      cupsGetDestMediaByName(http, dest, dinfo, "na_index_4x6in", flags, size))
    return (1);

 /*
  * Fall back to the first matching media size...
  */

  return (cupsGetDestMediaByIndex(http, dest, dinfo, 0, flags, size));
}


/*
 * 'cups_add_dconstres()' - Add a constraint or resolver to an array.
 */

static void
cups_add_dconstres(
    cups_array_t *a,			/* I - Array */
    ipp_t        *collection)		/* I - Collection value */
{
  ipp_attribute_t	*attr;		/* Attribute */
  _cups_dconstres_t	*temp;		/* Current constraint/resolver */


  if ((attr = ippFindAttribute(collection, "resolver-name",
                               IPP_TAG_NAME)) == NULL)
    return;

  if ((temp = calloc(1, sizeof(_cups_dconstres_t))) == NULL)
    return;

  temp->name       = attr->values[0].string.text;
  temp->collection = collection;

  cupsArrayAdd(a, temp);
}


/*
 * 'cups_compare_dconstres()' - Compare to resolver entries.
 */

static int				/* O - Result of comparison */
cups_compare_dconstres(
    _cups_dconstres_t *a,		/* I - First resolver */
    _cups_dconstres_t *b)		/* I - Second resolver */
{
  return (strcmp(a->name, b->name));
}


/*
 * 'cups_compare_media_db()' - Compare two media entries.
 */

static int				/* O - Result of comparison */
cups_compare_media_db(
    _cups_media_db_t *a,		/* I - First media entries */
    _cups_media_db_t *b)		/* I - Second media entries */
{
  int	result;				/* Result of comparison */


  if ((result = a->width - b->width) == 0)
    result = a->length - b->length;

  return (result);
}


/*
 * 'cups_copy_media_db()' - Copy a media entry.
 */

static _cups_media_db_t *		/* O - New media entry */
cups_copy_media_db(
    _cups_media_db_t *mdb)		/* I - Media entry to copy */
{
  _cups_media_db_t *temp;		/* New media entry */


  if ((temp = calloc(1, sizeof(_cups_media_db_t))) == NULL)
    return (NULL);

  if (mdb->color)
    temp->color = _cupsStrAlloc(mdb->color);
  if (mdb->key)
    temp->key = _cupsStrAlloc(mdb->key);
  if (mdb->info)
    temp->info = _cupsStrAlloc(mdb->info);
  if (mdb->size_name)
    temp->size_name = _cupsStrAlloc(mdb->size_name);
  if (mdb->source)
    temp->source = _cupsStrAlloc(mdb->source);
  if (mdb->type)
    temp->type = _cupsStrAlloc(mdb->type);

  temp->width  = mdb->width;
  temp->length = mdb->length;
  temp->bottom = mdb->bottom;
  temp->left   = mdb->left;
  temp->right  = mdb->right;
  temp->top    = mdb->top;

  return (temp);
}


/*
 * 'cups_create_cached()' - Create the media selection cache.
 */

static void
cups_create_cached(http_t       *http,	/* I - Connection to destination */
                   cups_dinfo_t *dinfo,	/* I - Destination information */
                   unsigned     flags)	/* I - Media selection flags */
{
  cups_array_t		*db;		/* Media database array to use */
  _cups_media_db_t	*mdb,		/* Media database entry */
			*first;		/* First entry this size */


  DEBUG_printf(("3cups_create_cached(http=%p, dinfo=%p, flags=%u)", (void *)http, (void *)dinfo, flags));

  if (dinfo->cached_db)
    cupsArrayDelete(dinfo->cached_db);

  dinfo->cached_db    = cupsArrayNew(NULL, NULL);
  dinfo->cached_flags = flags;

  if (flags & CUPS_MEDIA_FLAGS_READY)
  {
    DEBUG_puts("4cups_create_cached: ready media");

    cups_update_ready(http, dinfo);
    db = dinfo->ready_db;
  }
  else
  {
    DEBUG_puts("4cups_create_cached: supported media");

    if (!dinfo->media_db)
      cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);

    db = dinfo->media_db;
  }

  for (mdb = (_cups_media_db_t *)cupsArrayFirst(db), first = mdb;
       mdb;
       mdb = (_cups_media_db_t *)cupsArrayNext(db))
  {
    DEBUG_printf(("4cups_create_cached: %p key=\"%s\", type=\"%s\", %dx%d, B%d L%d R%d T%d", (void *)mdb, mdb->key, mdb->type, mdb->width, mdb->length, mdb->bottom, mdb->left, mdb->right, mdb->top));

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
      if (!mdb->left && !mdb->right && !mdb->top && !mdb->bottom)
      {
        DEBUG_printf(("4cups_create_cached: add %p", (void *)mdb));
        cupsArrayAdd(dinfo->cached_db, mdb);
      }
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
      if (first->width != mdb->width || first->length != mdb->length)
      {
	DEBUG_printf(("4cups_create_cached: add %p", (void *)first));
        cupsArrayAdd(dinfo->cached_db, first);
        first = mdb;
      }
      else if (mdb->left >= first->left && mdb->right >= first->right && mdb->top >= first->top && mdb->bottom >= first->bottom &&
	       (mdb->left != first->left || mdb->right != first->right || mdb->top != first->top || mdb->bottom != first->bottom))
        first = mdb;
    }
    else
    {
      DEBUG_printf(("4cups_create_cached: add %p", (void *)mdb));
      cupsArrayAdd(dinfo->cached_db, mdb);
    }
  }

  if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
  {
    DEBUG_printf(("4cups_create_cached: add %p", (void *)first));
    cupsArrayAdd(dinfo->cached_db, first);
  }
}


/*
 * 'cups_create_constraints()' - Create the constraints and resolvers arrays.
 */

static void
cups_create_constraints(
    cups_dinfo_t *dinfo)		/* I - Destination information */
{
  int			i;		/* Looping var */
  ipp_attribute_t	*attr;		/* Attribute */
  _ipp_value_t		*val;		/* Current value */


  dinfo->constraints = cupsArrayNew3(NULL, NULL, NULL, 0, NULL,
                                     (cups_afree_func_t)free);
  dinfo->resolvers   = cupsArrayNew3((cups_array_func_t)cups_compare_dconstres,
				     NULL, NULL, 0, NULL,
                                     (cups_afree_func_t)free);

  if ((attr = ippFindAttribute(dinfo->attrs, "job-constraints-supported",
			       IPP_TAG_BEGIN_COLLECTION)) != NULL)
  {
    for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
      cups_add_dconstres(dinfo->constraints, val->collection);
  }

  if ((attr = ippFindAttribute(dinfo->attrs, "job-resolvers-supported",
			       IPP_TAG_BEGIN_COLLECTION)) != NULL)
  {
    for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
      cups_add_dconstres(dinfo->resolvers, val->collection);
  }
}


/*
 * 'cups_create_defaults()' - Create the -default option array.
 *
 * TODO: Need to support collection defaults...
 */

static void
cups_create_defaults(
    cups_dinfo_t *dinfo)		/* I - Destination information */
{
  ipp_attribute_t	*attr;		/* Current attribute */
  char			name[IPP_MAX_NAME + 1],
					/* Current name */
			*nameptr,	/* Pointer into current name */
			value[2048];	/* Current value */


 /*
  * Iterate through the printer attributes looking for xxx-default and adding
  * xxx=value to the defaults option array.
  */

  for (attr = ippFirstAttribute(dinfo->attrs);
       attr;
       attr = ippNextAttribute(dinfo->attrs))
  {
    if (!attr->name || attr->group_tag != IPP_TAG_PRINTER)
      continue;

    if (attr->value_tag == IPP_TAG_BEGIN_COLLECTION)
      continue;				/* TODO: STR #4096 */

    if ((nameptr = attr->name + strlen(attr->name) - 8) <= attr->name ||
        strcmp(nameptr, "-default"))
      continue;

    strlcpy(name, attr->name, sizeof(name));
    if ((nameptr = name + strlen(name) - 8) <= name ||
        strcmp(nameptr, "-default"))
      continue;

    *nameptr = '\0';

    if (ippAttributeString(attr, value, sizeof(value)) >= sizeof(value))
      continue;

    dinfo->num_defaults = cupsAddOption(name, value, dinfo->num_defaults,
                                        &dinfo->defaults);
  }
}


/*
 * 'cups_create_media_db()' - Create the media database.
 */

static void
cups_create_media_db(
    cups_dinfo_t *dinfo,		/* I - Destination information */
    unsigned     flags)			/* I - Media flags */
{
  int			i;		/* Looping var */
  _ipp_value_t		*val;		/* Current value */
  ipp_attribute_t	*media_col_db,	/* media-col-database */
			*media_attr,	/* media-xxx */
			*x_dimension,	/* x-dimension */
			*y_dimension;	/* y-dimension */
  pwg_media_t		*pwg;		/* PWG media info */
  cups_array_t		*db;		/* New media database array */
  _cups_media_db_t	mdb;		/* Media entry */


  db = cupsArrayNew3((cups_array_func_t)cups_compare_media_db,
		     NULL, NULL, 0,
		     (cups_acopy_func_t)cups_copy_media_db,
		     (cups_afree_func_t)cups_free_media_db);

  if (flags == CUPS_MEDIA_FLAGS_READY)
  {
    dinfo->ready_db = db;

    media_col_db = ippFindAttribute(dinfo->ready_attrs, "media-col-ready",
				    IPP_TAG_BEGIN_COLLECTION);
    media_attr   = ippFindAttribute(dinfo->ready_attrs, "media-ready",
				    IPP_TAG_ZERO);
  }
  else
  {
    dinfo->media_db        = db;
    dinfo->min_size.width  = INT_MAX;
    dinfo->min_size.length = INT_MAX;
    dinfo->max_size.width  = 0;
    dinfo->max_size.length = 0;

    media_col_db = ippFindAttribute(dinfo->attrs, "media-col-database",
				    IPP_TAG_BEGIN_COLLECTION);
    media_attr   = ippFindAttribute(dinfo->attrs, "media-supported",
				    IPP_TAG_ZERO);
  }

  if (media_col_db)
  {
    _ipp_value_t	*custom = NULL;	/* Custom size range value */

    for (i = media_col_db->num_values, val = media_col_db->values;
         i > 0;
         i --, val ++)
    {
      memset(&mdb, 0, sizeof(mdb));

      if ((media_attr = ippFindAttribute(val->collection, "media-size",
                                         IPP_TAG_BEGIN_COLLECTION)) != NULL)
      {
        ipp_t	*media_size = media_attr->values[0].collection;
					/* media-size collection value */

        if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
                                            IPP_TAG_INTEGER)) != NULL &&
	    (y_dimension = ippFindAttribute(media_size, "y-dimension",
					    IPP_TAG_INTEGER)) != NULL)
	{
	 /*
	  * Fixed size...
	  */

	  mdb.width  = x_dimension->values[0].integer;
	  mdb.length = y_dimension->values[0].integer;
	}
	else if ((x_dimension = ippFindAttribute(media_size, "x-dimension",
						 IPP_TAG_INTEGER)) != NULL &&
		 (y_dimension = ippFindAttribute(media_size, "y-dimension",
						 IPP_TAG_RANGE)) != NULL)
	{
	 /*
	  * Roll limits...
	  */

	  mdb.width  = x_dimension->values[0].integer;
	  mdb.length = y_dimension->values[0].range.upper;
	}
        else if (flags != CUPS_MEDIA_FLAGS_READY &&
                 (x_dimension = ippFindAttribute(media_size, "x-dimension",
					         IPP_TAG_RANGE)) != NULL &&
		 (y_dimension = ippFindAttribute(media_size, "y-dimension",
						 IPP_TAG_RANGE)) != NULL)
	{
	 /*
	  * Custom size range; save this as the custom size value with default
	  * margins, then continue; we'll capture the real margins below...
	  */

	  custom = val;

	  dinfo->min_size.width  = x_dimension->values[0].range.lower;
	  dinfo->min_size.length = y_dimension->values[0].range.lower;
	  dinfo->min_size.left   =
	  dinfo->min_size.right  = 635; /* Default 1/4" side margins */
	  dinfo->min_size.top    =
	  dinfo->min_size.bottom = 1270; /* Default 1/2" top/bottom margins */

	  dinfo->max_size.width  = x_dimension->values[0].range.upper;
	  dinfo->max_size.length = y_dimension->values[0].range.upper;
	  dinfo->max_size.left   =
	  dinfo->max_size.right  = 635; /* Default 1/4" side margins */
	  dinfo->max_size.top    =
	  dinfo->max_size.bottom = 1270; /* Default 1/2" top/bottom margins */
	  continue;
	}
      }

      if ((media_attr = ippFindAttribute(val->collection, "media-color",
                                         IPP_TAG_ZERO)) != NULL &&
          (media_attr->value_tag == IPP_TAG_NAME ||
           media_attr->value_tag == IPP_TAG_NAMELANG ||
           media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.color = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-info",
                                         IPP_TAG_TEXT)) != NULL)
        mdb.info = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-key",
                                         IPP_TAG_ZERO)) != NULL &&
          (media_attr->value_tag == IPP_TAG_NAME ||
           media_attr->value_tag == IPP_TAG_NAMELANG ||
           media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.key = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-size-name",
                                         IPP_TAG_ZERO)) != NULL &&
          (media_attr->value_tag == IPP_TAG_NAME ||
           media_attr->value_tag == IPP_TAG_NAMELANG ||
           media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.size_name = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-source",
                                         IPP_TAG_ZERO)) != NULL &&
          (media_attr->value_tag == IPP_TAG_NAME ||
           media_attr->value_tag == IPP_TAG_NAMELANG ||
           media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.source = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-type",
                                         IPP_TAG_ZERO)) != NULL &&
          (media_attr->value_tag == IPP_TAG_NAME ||
           media_attr->value_tag == IPP_TAG_NAMELANG ||
           media_attr->value_tag == IPP_TAG_KEYWORD))
        mdb.type = media_attr->values[0].string.text;

      if ((media_attr = ippFindAttribute(val->collection, "media-bottom-margin",
                                         IPP_TAG_INTEGER)) != NULL)
        mdb.bottom = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-left-margin",
                                         IPP_TAG_INTEGER)) != NULL)
        mdb.left = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-right-margin",
                                         IPP_TAG_INTEGER)) != NULL)
        mdb.right = media_attr->values[0].integer;

      if ((media_attr = ippFindAttribute(val->collection, "media-top-margin",
                                         IPP_TAG_INTEGER)) != NULL)
        mdb.top = media_attr->values[0].integer;

      cupsArrayAdd(db, &mdb);
    }

    if (custom)
    {
      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-bottom-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.top =
        dinfo->max_size.top = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-left-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.left =
        dinfo->max_size.left = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-right-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.right =
        dinfo->max_size.right = media_attr->values[0].integer;
      }

      if ((media_attr = ippFindAttribute(custom->collection,
                                         "media-top-margin",
                                         IPP_TAG_INTEGER)) != NULL)
      {
        dinfo->min_size.top =
        dinfo->max_size.top = media_attr->values[0].integer;
      }
    }
  }
  else if (media_attr &&
           (media_attr->value_tag == IPP_TAG_NAME ||
            media_attr->value_tag == IPP_TAG_NAMELANG ||
            media_attr->value_tag == IPP_TAG_KEYWORD))
  {
    memset(&mdb, 0, sizeof(mdb));

    mdb.left   =
    mdb.right  = 635; /* Default 1/4" side margins */
    mdb.top    =
    mdb.bottom = 1270; /* Default 1/2" top/bottom margins */

    for (i = media_attr->num_values, val = media_attr->values;
         i > 0;
         i --, val ++)
    {
      if ((pwg = pwgMediaForPWG(val->string.text)) == NULL)
        if ((pwg = pwgMediaForLegacy(val->string.text)) == NULL)
	{
	  DEBUG_printf(("3cups_create_media_db: Ignoring unknown size '%s'.",
			val->string.text));
	  continue;
	}

      mdb.width  = pwg->width;
      mdb.length = pwg->length;

      if (flags != CUPS_MEDIA_FLAGS_READY &&
          !strncmp(val->string.text, "custom_min_", 11))
      {
        mdb.size_name   = NULL;
        dinfo->min_size = mdb;
      }
      else if (flags != CUPS_MEDIA_FLAGS_READY &&
	       !strncmp(val->string.text, "custom_max_", 11))
      {
        mdb.size_name   = NULL;
        dinfo->max_size = mdb;
      }
      else
      {
        mdb.size_name = val->string.text;

        cupsArrayAdd(db, &mdb);
      }
    }
  }
}


/*
 * 'cups_free_media_cb()' - Free a media entry.
 */

static void
cups_free_media_db(
    _cups_media_db_t *mdb)		/* I - Media entry to free */
{
  if (mdb->color)
    _cupsStrFree(mdb->color);
  if (mdb->key)
    _cupsStrFree(mdb->key);
  if (mdb->info)
    _cupsStrFree(mdb->info);
  if (mdb->size_name)
    _cupsStrFree(mdb->size_name);
  if (mdb->source)
    _cupsStrFree(mdb->source);
  if (mdb->type)
    _cupsStrFree(mdb->type);

  free(mdb);
}


/*
 * 'cups_get_media_db()' - Lookup the media entry for a given size.
 */

static int				/* O - 1 on match, 0 on failure */
cups_get_media_db(http_t       *http,	/* I - Connection to destination */
                  cups_dinfo_t *dinfo,	/* I - Destination information */
                  pwg_media_t  *pwg,	/* I - PWG media info */
                  unsigned     flags,	/* I - Media matching flags */
                  cups_size_t  *size)	/* O - Media size/margin/name info */
{
  cups_array_t		*db;		/* Which media database to query */
  _cups_media_db_t	*mdb,		/* Current media database entry */
			*best = NULL,	/* Best matching entry */
			key;		/* Search key */


 /*
  * Create the media database as needed...
  */

  if (flags & CUPS_MEDIA_FLAGS_READY)
  {
    cups_update_ready(http, dinfo);
    db = dinfo->ready_db;
  }
  else
  {
    if (!dinfo->media_db)
      cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_DEFAULT);

    db = dinfo->media_db;
  }

 /*
  * Find a match...
  */

  memset(&key, 0, sizeof(key));
  key.width  = pwg->width;
  key.length = pwg->length;

  if ((mdb = cupsArrayFind(db, &key)) != NULL)
  {
   /*
    * Found an exact match, let's figure out the best margins for the flags
    * supplied...
    */

    best = mdb;

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
     /*
      * Look for the smallest margins...
      */

      if (best->left != 0 || best->right != 0 || best->top != 0 || best->bottom != 0)
      {
	for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	     mdb && !cups_compare_media_db(mdb, &key);
	     mdb = (_cups_media_db_t *)cupsArrayNext(db))
	{
	  if (mdb->left <= best->left && mdb->right <= best->right &&
	      mdb->top <= best->top && mdb->bottom <= best->bottom)
	  {
	    best = mdb;
	    if (mdb->left == 0 && mdb->right == 0 && mdb->bottom == 0 &&
		mdb->top == 0)
	      break;
	  }
	}
      }

     /*
      * If we need an exact match, return no-match if the size is not
      * borderless.
      */

      if ((flags & CUPS_MEDIA_FLAGS_EXACT) &&
          (best->left || best->right || best->top || best->bottom))
        return (0);
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
     /*
      * Look for the largest margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && !cups_compare_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (mdb->left >= best->left && mdb->right >= best->right &&
	    mdb->top >= best->top && mdb->bottom >= best->bottom &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
    else
    {
     /*
      * Look for the smallest non-zero margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && !cups_compare_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
	    ((mdb->right > 0 && mdb->right <= best->right) || best->right == 0) &&
	    ((mdb->top > 0 && mdb->top <= best->top) || best->top == 0) &&
	    ((mdb->bottom > 0 && mdb->bottom <= best->bottom) || best->bottom == 0) &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
  }
  else if (flags & CUPS_MEDIA_FLAGS_EXACT)
  {
   /*
    * See if we can do this as a custom size...
    */

    if (pwg->width < dinfo->min_size.width ||
        pwg->width > dinfo->max_size.width ||
        pwg->length < dinfo->min_size.length ||
        pwg->length > dinfo->max_size.length)
      return (0);			/* Out of range */

    if ((flags & CUPS_MEDIA_FLAGS_BORDERLESS) &&
        (dinfo->min_size.left > 0 || dinfo->min_size.right > 0 ||
         dinfo->min_size.top > 0 || dinfo->min_size.bottom > 0))
      return (0);			/* Not borderless */

    key.size_name = (char *)pwg->pwg;
    key.bottom    = dinfo->min_size.bottom;
    key.left      = dinfo->min_size.left;
    key.right     = dinfo->min_size.right;
    key.top       = dinfo->min_size.top;

    best = &key;
  }
  else if (pwg->width >= dinfo->min_size.width &&
	   pwg->width <= dinfo->max_size.width &&
	   pwg->length >= dinfo->min_size.length &&
	   pwg->length <= dinfo->max_size.length)
  {
   /*
    * Map to custom size...
    */

    key.size_name = (char *)pwg->pwg;
    key.bottom    = dinfo->min_size.bottom;
    key.left      = dinfo->min_size.left;
    key.right     = dinfo->min_size.right;
    key.top       = dinfo->min_size.top;

    best = &key;
  }
  else
  {
   /*
    * Find a close size...
    */

    for (mdb = (_cups_media_db_t *)cupsArrayFirst(db);
         mdb;
         mdb = (_cups_media_db_t *)cupsArrayNext(db))
      if (cups_is_close_media_db(mdb, &key))
        break;

    if (!mdb)
      return (0);

    best = mdb;

    if (flags & CUPS_MEDIA_FLAGS_BORDERLESS)
    {
     /*
      * Look for the smallest margins...
      */

      if (best->left != 0 || best->right != 0 || best->top != 0 ||
          best->bottom != 0)
      {
	for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	     mdb && cups_is_close_media_db(mdb, &key);
	     mdb = (_cups_media_db_t *)cupsArrayNext(db))
	{
	  if (mdb->left <= best->left && mdb->right <= best->right &&
	      mdb->top <= best->top && mdb->bottom <= best->bottom &&
	      (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  {
	    best = mdb;
	    if (mdb->left == 0 && mdb->right == 0 && mdb->bottom == 0 &&
		mdb->top == 0)
	      break;
	  }
	}
      }
    }
    else if (flags & CUPS_MEDIA_FLAGS_DUPLEX)
    {
     /*
      * Look for the largest margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && cups_is_close_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (mdb->left >= best->left && mdb->right >= best->right &&
	    mdb->top >= best->top && mdb->bottom >= best->bottom &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
    else
    {
     /*
      * Look for the smallest non-zero margins...
      */

      for (mdb = (_cups_media_db_t *)cupsArrayNext(db);
	   mdb && cups_is_close_media_db(mdb, &key);
	   mdb = (_cups_media_db_t *)cupsArrayNext(db))
      {
	if (((mdb->left > 0 && mdb->left <= best->left) || best->left == 0) &&
	    ((mdb->right > 0 && mdb->right <= best->right) ||
	     best->right == 0) &&
	    ((mdb->top > 0 && mdb->top <= best->top) || best->top == 0) &&
	    ((mdb->bottom > 0 && mdb->bottom <= best->bottom) ||
	     best->bottom == 0) &&
	    (mdb->bottom != best->bottom || mdb->left != best->left || mdb->right != best->right || mdb->top != best->top))
	  best = mdb;
      }
    }
  }

  if (best)
  {
   /*
    * Return the matching size...
    */

    if (best->size_name)
      strlcpy(size->media, best->size_name, sizeof(size->media));
    else if (best->key)
      strlcpy(size->media, best->key, sizeof(size->media));
    else
      strlcpy(size->media, pwg->pwg, sizeof(size->media));

    size->width  = best->width;
    size->length = best->length;
    size->bottom = best->bottom;
    size->left   = best->left;
    size->right  = best->right;
    size->top    = best->top;

    return (1);
  }

  return (0);
}


/*
 * 'cups_is_close_media_db()' - Compare two media entries to see if they are
 *                              close to the same size.
 *
 * Currently we use 5 points (from PostScript) as the matching range...
 */

static int				/* O - 1 if the sizes are close */
cups_is_close_media_db(
    _cups_media_db_t *a,		/* I - First media entries */
    _cups_media_db_t *b)		/* I - Second media entries */
{
  int	dwidth,				/* Difference in width */
	dlength;			/* Difference in length */


  dwidth  = a->width - b->width;
  dlength = a->length - b->length;

  return (dwidth >= -176 && dwidth <= 176 &&
          dlength >= -176 && dlength <= 176);
}


/*
 * 'cups_test_constraints()' - Test constraints.
 *
 * TODO: STR #4096 - Need to properly support media-col contraints...
 */

static cups_array_t *			/* O - Active constraints */
cups_test_constraints(
    cups_dinfo_t  *dinfo,		/* I - Destination information */
    const char    *new_option,		/* I - Newly selected option */
    const char    *new_value,		/* I - Newly selected value */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    int           *num_conflicts,	/* O - Number of conflicting options */
    cups_option_t **conflicts)		/* O - Conflicting options */
{
  int			i,		/* Looping var */
			match;		/* Value matches? */
  int			num_matching;	/* Number of matching options */
  cups_option_t		*matching;	/* Matching options */
  _cups_dconstres_t	*c;		/* Current constraint */
  cups_array_t		*active = NULL;	/* Active constraints */
  ipp_attribute_t	*attr;		/* Current attribute */
  _ipp_value_t		*attrval;	/* Current attribute value */
  const char		*value;		/* Current value */
  char			temp[1024];	/* Temporary string */
  int			int_value;	/* Integer value */
  int			xres_value,	/* Horizontal resolution */
			yres_value;	/* Vertical resolution */
  ipp_res_t		units_value;	/* Resolution units */


  for (c = (_cups_dconstres_t *)cupsArrayFirst(dinfo->constraints);
       c;
       c = (_cups_dconstres_t *)cupsArrayNext(dinfo->constraints))
  {
    num_matching = 0;
    matching     = NULL;

    for (attr = ippFirstAttribute(c->collection);
         attr;
         attr = ippNextAttribute(c->collection))
    {
      if (attr->value_tag == IPP_TAG_BEGIN_COLLECTION)
        break;				/* TODO: STR #4096 */

     /*
      * Get the value for the current attribute in the constraint...
      */

      if (new_option && new_value && !strcmp(attr->name, new_option))
        value = new_value;
      else if ((value = cupsGetOption(attr->name, num_options,
                                      options)) == NULL)
        value = cupsGetOption(attr->name, dinfo->num_defaults, dinfo->defaults);

      if (!value)
      {
       /*
        * Not set so this constraint does not apply...
        */

        break;
      }

      match = 0;

      switch (attr->value_tag)
      {
        case IPP_TAG_INTEGER :
        case IPP_TAG_ENUM :
	    int_value = atoi(value);

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (attrval->integer == int_value)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_BOOLEAN :
	    int_value = !strcmp(value, "true");

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (attrval->boolean == int_value)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_RANGE :
	    int_value = atoi(value);

	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (int_value >= attrval->range.lower &&
	          int_value <= attrval->range.upper)
	      {
		match = 1;
		break;
	      }
            }
            break;

        case IPP_TAG_RESOLUTION :
	    if (sscanf(value, "%dx%d%15s", &xres_value, &yres_value, temp) != 3)
	    {
	      if (sscanf(value, "%d%15s", &xres_value, temp) != 2)
		break;

	      yres_value = xres_value;
	    }

	    if (!strcmp(temp, "dpi"))
	      units_value = IPP_RES_PER_INCH;
	    else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm"))
	      units_value = IPP_RES_PER_CM;
	    else
	      break;

	    for (i = attr->num_values, attrval = attr->values;
		 i > 0;
		 i --, attrval ++)
	    {
	      if (attrval->resolution.xres == xres_value &&
		  attrval->resolution.yres == yres_value &&
		  attrval->resolution.units == units_value)
	      {
	      	match = 1;
		break;
	      }
	    }
            break;

	case IPP_TAG_TEXT :
	case IPP_TAG_NAME :
	case IPP_TAG_KEYWORD :
	case IPP_TAG_CHARSET :
	case IPP_TAG_URI :
	case IPP_TAG_URISCHEME :
	case IPP_TAG_MIMETYPE :
	case IPP_TAG_LANGUAGE :
	case IPP_TAG_TEXTLANG :
	case IPP_TAG_NAMELANG :
	    for (i = attr->num_values, attrval = attr->values;
	         i > 0;
	         i --, attrval ++)
	    {
	      if (!strcmp(attrval->string.text, value))
	      {
		match = 1;
		break;
	      }
            }
	    break;

        default :
            break;
      }

      if (!match)
        break;

      num_matching = cupsAddOption(attr->name, value, num_matching, &matching);
    }

    if (!attr)
    {
      if (!active)
        active = cupsArrayNew(NULL, NULL);

      cupsArrayAdd(active, c);

      if (num_conflicts && conflicts)
      {
        cups_option_t	*moption;	/* Matching option */

        for (i = num_matching, moption = matching; i > 0; i --, moption ++)
          *num_conflicts = cupsAddOption(moption->name, moption->value,
					 *num_conflicts, conflicts);
      }
    }

    cupsFreeOptions(num_matching, matching);
  }

  return (active);
}


/*
 * 'cups_update_ready()' - Update xxx-ready attributes for the printer.
 */

static void
cups_update_ready(http_t       *http,	/* I - Connection to destination */
                  cups_dinfo_t *dinfo)	/* I - Destination information */
{
  ipp_t	*request;			/* Get-Printer-Attributes request */
  static const char * const pattrs[] =	/* Printer attributes we want */
  {
    "finishings-col-ready",
    "finishings-ready",
    "job-finishings-col-ready",
    "job-finishings-ready",
    "media-col-ready",
    "media-ready"
  };


 /*
  * Don't update more than once every 30 seconds...
  */

  if ((time(NULL) - dinfo->ready_time) < _CUPS_MEDIA_READY_TTL)
    return;

 /*
  * Free any previous results...
  */

  if (dinfo->cached_flags & CUPS_MEDIA_FLAGS_READY)
  {
    cupsArrayDelete(dinfo->cached_db);
    dinfo->cached_db    = NULL;
    dinfo->cached_flags = CUPS_MEDIA_FLAGS_DEFAULT;
  }

  ippDelete(dinfo->ready_attrs);
  dinfo->ready_attrs = NULL;

  cupsArrayDelete(dinfo->ready_db);
  dinfo->ready_db = NULL;

 /*
  * Query the xxx-ready values...
  */

  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  ippSetVersion(request, dinfo->version / 10, dinfo->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
               dinfo->uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);

  dinfo->ready_attrs = cupsDoRequest(http, request, dinfo->resource);

 /*
  * Update the ready media database...
  */

  cups_create_media_db(dinfo, CUPS_MEDIA_FLAGS_READY);

 /*
  * Update last lookup time and return...
  */

  dinfo->ready_time = time(NULL);
}
