/*
 * Copyright (C) 2016 The Android Open Source Project
 * Copyright (C) 2016 Mopria Alliance, Inc.
 * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "lib_wprint.h"
#include "cups.h"
#include "http-private.h"
#include "ipphelper.h"
#include "wprint_debug.h"

#include "ipp_print.h"
#include "../plugins/media.h"

#define TAG "ipphelper"

/*
 * Get the IPP version of the given printer
 */
static status_t determine_ipp_version(char *, http_t *);

/*
 * Tests IPP versions and sets it to the latest working version
 */
static status_t test_and_set_ipp_version(char *, http_t *, int, int);

/*
 * Parses supported IPP versions from the IPP response and copies them into ippVersions
 */
static void parse_IPPVersions(ipp_t *response, ipp_version_supported_t *ippVersions);

/*
 * Parses printer URIs from the IPP response and copies them into capabilities
 */
static void parse_printerUris(ipp_t *response, printer_capabilities_t *capabilities);

/*
 * Known media sizes.
 *
 * A note on rounding: In some cases the Android-specified width (in mils) is rounded down.
 * This causes artifacts in libjpeg-turbo when rendering to the correct width, so in these
 * cases we override with a rounded-up value.
 */
struct MediaSizeTableElement SupportedMediaSizes[SUPPORTED_MEDIA_SIZE_COUNT] = {
        { US_LETTER, "LETTER", 8500, 11000, UNKNOWN_VALUE, UNKNOWN_VALUE, "na_letter_8.5x11in" },
        { US_LEGAL, "LEGAL", 8500, 14000, UNKNOWN_VALUE, UNKNOWN_VALUE, "na_legal_8.5x14in" },
        { LEDGER, "LEDGER", 11000, 17000, UNKNOWN_VALUE, UNKNOWN_VALUE, "na_ledger_11x17in" },
        { INDEX_CARD_5X7, "5X7", 5000, 7000, UNKNOWN_VALUE, UNKNOWN_VALUE, "na_5x7_5x7in" },

        // Android system uses width of 11690
        { ISO_A3, "A3", 11694, 16540, 297, 420, "iso_a3_297x420mm" },

        // Android system uses width of 8267
        { ISO_A4, "A4", 8268, 11692, 210, 297, "iso_a4_210x297mm" },
        { ISO_A5, "A5", 5830, 8270, 148, 210, "iso_a5_148x210mm" },

        // Android system uses width of 10118
        { JIS_B4, "JIS B4", 10119, 14331, 257, 364, "jis_b4_257x364mm" },

        // Android system uses width of 7165
        { JIS_B5, "JIS B5", 7167, 10118, 182, 257, "jis_b5_182x257mm" },
        { US_GOVERNMENT_LETTER, "8x10", 8000, 10000, UNKNOWN_VALUE, UNKNOWN_VALUE,
        "na_govt-letter_8x10in" },
        { INDEX_CARD_4X6, "4x6", 4000, 6000, UNKNOWN_VALUE, UNKNOWN_VALUE, "na_index-4x6_4x6in" },
        { JPN_HAGAKI_PC, "JPOST", 3940, 5830, 100, 148, "jpn_hagaki_100x148mm" },
        { PHOTO_89X119, "89X119", 3504, 4685, 89, 119, "om_dsc-photo_89x119mm" },
        { CARD_54X86, "54X86", 2126, 3386, 54, 86, "om_card_54x86mm" },
        { OE_PHOTO_L, "L", 3500, 5000, UNKNOWN_VALUE, UNKNOWN_VALUE, "oe_photo-l_3.5x5in" }
};

typedef struct {
    double Lower;
    double Upper;
} media_dimension_mm_t;

static const char *__request_ipp_version[] = {"ipp-versions-supported"};

static int __ipp_version_major = 2;
static int __ipp_version_minor = 0;

status_t set_ipp_version(ipp_t *op_to_set, char *printer_uri, http_t *http,
        ipp_version_state use_existing_version) {
    LOGD("set_ipp_version(): Enter %d", use_existing_version);
    if (op_to_set == NULL) {
        return ERROR;
    }
    switch (use_existing_version) {
        case NEW_REQUEST_SEQUENCE:
            __ipp_version_major = 2;
            __ipp_version_minor = 0;
            break;
        case IPP_VERSION_RESOLVED:
            break;
        case IPP_VERSION_UNSUPPORTED:
            if (determine_ipp_version(printer_uri, http) != 0) {
                return ERROR;
            }
            break;
    }
    ippSetVersion(op_to_set, __ipp_version_major, __ipp_version_minor);
    LOGD("set_ipp_version(): Done");
    return OK;
}

static status_t determine_ipp_version(char *printer_uri, http_t *http) {
    LOGD("determine_ipp_version(): Enter printer_uri =  %s", printer_uri);

    if (http == NULL) {
        LOGE("determine_ipp_version(): http is NULL cannot continue");
        return ERROR;
    }
    if ((test_and_set_ipp_version(printer_uri, http, 1, 1) == OK)
            || (test_and_set_ipp_version(printer_uri, http, 1, 0) == OK)
            || (test_and_set_ipp_version(printer_uri, http, 2, 0) == OK)) {
        LOGD("successfully set ipp version.");
    } else {
        LOGD("could not get ipp version using any known ipp version.");
        return ERROR;
    }
    return OK;
}

static status_t test_and_set_ipp_version(char *printer_uri, http_t *http, int major, int minor) {
    status_t return_value = ERROR;
    int service_unavailable_retry_count = 0;
    int bad_request_retry_count = 0;
    ipp_t *request = NULL;
    ipp_t *response;
    ipp_version_supported_t ippVersions;
    char http_resource[1024];
    int op = IPP_GET_PRINTER_ATTRIBUTES;

    LOGD("test_and_set_ipp_version(): Enter %d - %d", major, minor);
    memset(&ippVersions, 0, sizeof(ipp_version_supported_t));
    getResourceFromURI(printer_uri, http_resource, 1024);
    do {
        request = ippNewRequest(op);
        ippSetVersion(request, major, minor);
        ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri);
        ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes",
                sizeof(__request_ipp_version) / sizeof(__request_ipp_version[0]),
                NULL, __request_ipp_version);
        if ((response = cupsDoRequest(http, request, http_resource)) == NULL) {
            ipp_status_t ipp_status = cupsLastError();
            LOGD("test_and_set_ipp_version:  response is null:  ipp_status %d %s",
                    ipp_status, ippErrorString(ipp_status));
            if (ipp_status == IPP_INTERNAL_ERROR) {
                LOGE("test_and_set_ipp_version: 1280 received, bailing...");
                break;
            } else if ((ipp_status == IPP_SERVICE_UNAVAILABLE) &&
                    (service_unavailable_retry_count < IPP_SERVICE_ERROR_MAX_RETRIES)) {
                LOGE("test_and_set_ipp_version: 1282 received, retrying %d of %d",
                        service_unavailable_retry_count, IPP_SERVICE_ERROR_MAX_RETRIES);
                service_unavailable_retry_count++;
                continue;
            } else if (ipp_status == IPP_BAD_REQUEST) {
                LOGE("test_and_set_ipp_version: IPP_Status of IPP_BAD_REQUEST "
                        "received. retry (%d) of (%d)", bad_request_retry_count,
                        IPP_BAD_REQUEST_MAX_RETRIES);
                if (bad_request_retry_count > IPP_BAD_REQUEST_MAX_RETRIES) {
                    break;
                }
                bad_request_retry_count++;
                continue;
            } else if (ipp_status == IPP_NOT_FOUND) {
                LOGE("test_and_set_ipp_version: IPP_Status of IPP_NOT_FOUND received");
                break;
            }
            return_value = ERROR;
        } else {
            ipp_status_t ipp_status = cupsLastError();
            LOGD("ipp CUPS last ERROR: %d, %s", ipp_status, ippErrorString(ipp_status));
            if (ipp_status == IPP_BAD_REQUEST) {
                LOGD("IPP_Status of IPP_BAD_REQUEST received. retry (%d) of (%d)",
                        bad_request_retry_count, IPP_BAD_REQUEST_MAX_RETRIES);
                if (bad_request_retry_count > IPP_BAD_REQUEST_MAX_RETRIES) {
                    break;
                }
                bad_request_retry_count++;
                ippDelete(response);
                continue;
            }

            parse_IPPVersions(response, &ippVersions);
            if (ippVersions.supportsIpp20) {
                __ipp_version_major = 2;
                __ipp_version_minor = 0;
                return_value = OK;
                LOGD("test_and_set_ipp_version(): ipp version set to %d,%d",
                        __ipp_version_major, __ipp_version_minor);
            } else if (ippVersions.supportsIpp11) {
                __ipp_version_major = 1;
                __ipp_version_minor = 1;
                return_value = OK;
                LOGD("test_and_set_ipp_version(): ipp version set to %d,%d",
                        __ipp_version_major, __ipp_version_minor);
            } else if (ippVersions.supportsIpp10) {
                __ipp_version_major = 1;
                __ipp_version_minor = 0;
                return_value = OK;
                LOGD("test_and_set_ipp_version(): ipp version set to %d,%d",
                        __ipp_version_major, __ipp_version_minor);
            } else {
                LOGD("test_and_set_ipp_version: ipp version not found");
                return_value = ERROR;
            }
        }
        if (response != NULL) ippDelete(response);
        break;
    } while (1);
    return return_value;
}

ipp_status_t get_PrinterState(http_t *http, char *printer_uri,
        printer_state_dyn_t *printer_state_dyn, ipp_pstate_t *printer_state) {
    LOGD("get_PrinterState(): Enter");

    // Requested printer attributes
    static const char *pattrs[] = {"printer-make-and-model", "printer-state",
            "printer-state-message", "printer-state-reasons"};

    ipp_t *request = NULL;
    ipp_t *response = NULL;
    ipp_status_t ipp_status = IPP_OK;
    int op = IPP_GET_PRINTER_ATTRIBUTES;
    char http_resource[1024];
    getResourceFromURI(printer_uri, http_resource, 1024);

    if (printer_state_dyn == NULL) {
        LOGE("get_PrinterState(): printer_state_dyn is null");
        return ipp_status;
    }

    if (printer_state) {
        *printer_state = IPP_PRINTER_STOPPED;
    } else {
        LOGE("get_PrinterState(): printer_state is null");
    }
    request = ippNewRequest(op);

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri);

    ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes",
            sizeof(pattrs) / sizeof(pattrs[0]), NULL, pattrs);

    if ((response = ipp_doCupsRequest(http, request, http_resource, printer_uri)) == NULL) {
        ipp_status = cupsLastError();
        LOGE("get_PrinterState(): response is null: ipp_status %d", ipp_status);
        printer_state_dyn->printer_status = PRINT_STATUS_UNABLE_TO_CONNECT;
        printer_state_dyn->printer_reasons[0] = PRINT_STATUS_UNABLE_TO_CONNECT;
    } else {
        ipp_status = cupsLastError();
        LOGD("ipp CUPS last ERROR: %d, %s", ipp_status, ippErrorString(ipp_status));
        get_PrinterStateReason(response, printer_state, printer_state_dyn);
        LOGD("get_PrinterState(): printer_state_dyn->printer_status: %d",
                printer_state_dyn->printer_status);
    }
    LOGD("get_PrinterState(): exit http->fd %d, ipp_status %d, printer_state %d", http->fd,
            ipp_status, printer_state_dyn->printer_status);

    ippDelete(request);
    ippDelete(response);
    return ipp_status;
}

void get_PrinterStateReason(ipp_t *response, ipp_pstate_t *printer_state,
        printer_state_dyn_t *printer_state_dyn) {
    LOGD("get_PrinterStateReason(): Enter");
    ipp_attribute_t *attrptr;
    int reason_idx = 0;
    int idx = 0;
    ipp_pstate_t printer_ippstate = IPP_PRINTER_IDLE;

    if ((attrptr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) == NULL) {
        LOGE("get_PrinterStateReason printer-state null");
        printer_state_dyn->printer_status = PRINT_STATUS_UNABLE_TO_CONNECT;
        printer_state_dyn->printer_reasons[0] = PRINT_STATUS_UNABLE_TO_CONNECT;
    } else {
        printer_ippstate = (ipp_pstate_t) ippGetInteger(attrptr, 0);
        *printer_state = printer_ippstate;

        LOGD("get_PrinterStateReason printer-state: %d", printer_ippstate);
        // set the printer_status; they may be modified based on the status reasons below.
        switch (printer_ippstate) {
            case IPP_PRINTER_IDLE:
                printer_state_dyn->printer_status = PRINT_STATUS_IDLE;
                break;
            case IPP_PRINTER_PROCESSING:
                printer_state_dyn->printer_status = PRINT_STATUS_PRINTING;
                break;
            case IPP_PRINTER_STOPPED:
                printer_state_dyn->printer_status = PRINT_STATUS_SVC_REQUEST;
                break;
        }
    }

    if ((attrptr = ippFindAttribute(response, "printer-state-reasons", IPP_TAG_KEYWORD)) == NULL) {
        LOGE(" get_PrinterStateReason printer-state reason null");
        printer_state_dyn->printer_status = PRINT_STATUS_UNABLE_TO_CONNECT;
        printer_state_dyn->printer_reasons[0] = PRINT_STATUS_UNABLE_TO_CONNECT;
    } else {
        for (idx = 0; idx < ippGetCount(attrptr); idx++) {
            // Per RFC2911 any of these can have -error, -warning, or -report appended to end
            LOGD("get_PrinterStateReason printer-state-reason: %s",
                    ippGetString(attrptr, idx, NULL));
            if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_NONE,
                    strlen(IPP_PRNT_STATE_NONE)) == 0) {
                switch (printer_ippstate) {
                    case IPP_PRINTER_IDLE:
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_IDLE;
                        break;
                    case IPP_PRINTER_PROCESSING:
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_PRINTING;
                        break;
                    case IPP_PRINTER_STOPPED:
                        // should this be PRINT_STATUS_SVC_REQUEST
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_UNKNOWN;
                        break;
                }
            } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_SPOOL_FULL,
                    strlen(IPP_PRNT_STATE_SPOOL_FULL)) == 0) {
                switch (printer_ippstate) {
                    case IPP_PRINTER_IDLE:
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_UNKNOWN;
                        break;
                    case IPP_PRINTER_PROCESSING:
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_PRINTING;
                        break;
                    case IPP_PRINTER_STOPPED:
                        // should this be PRINT_STATUS_SVC_REQUEST
                        printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_UNKNOWN;
                        break;
                }
            } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_MARKER_SUPPLY_LOW,
                    strlen(IPP_PRNT_STATE_MARKER_SUPPLY_LOW)) == 0) {
                printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_LOW_ON_INK;
            } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_TONER_LOW,
                    strlen(IPP_PRNT_STATE_TONER_LOW)) == 0) {
                printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_LOW_ON_TONER;
            } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_OTHER_WARN,
                    strlen(IPP_PRNT_STATE_OTHER_WARN)) == 0) {
                printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_UNKNOWN;
            } else {
                // check blocking cases
                if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_MEDIA_NEEDED,
                        strlen(IPP_PRNT_STATE_MEDIA_NEEDED)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_OUT_OF_PAPER;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_MEDIA_EMPTY,
                        strlen(IPP_PRNT_STATE_MEDIA_EMPTY)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_OUT_OF_PAPER;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_TONER_EMPTY,
                        strlen(IPP_PRNT_STATE_TONER_EMPTY)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_OUT_OF_TONER;
                } else if (strncmp(ippGetString(attrptr, idx, NULL),
                        IPP_PRNT_STATE_MARKER_SUPPLY_EMPTY,
                        strlen(IPP_PRNT_STATE_MARKER_SUPPLY_EMPTY)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_OUT_OF_INK;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_DOOR_OPEN,
                        strlen(IPP_PRNT_STATE_DOOR_OPEN)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_DOOR_OPEN;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_COVER_OPEN,
                        strlen(IPP_PRNT_STATE_COVER_OPEN)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_DOOR_OPEN;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_MEDIA_JAM,
                        strlen(IPP_PRNT_STATE_MEDIA_JAM)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_JAMMED;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_SHUTDOWN,
                        strlen(IPP_PRNT_SHUTDOWN)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_SHUTTING_DOWN;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_STATE_OTHER_ERR,
                        strlen(IPP_PRNT_STATE_OTHER_ERR)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_SVC_REQUEST;
                } else if (strncmp(ippGetString(attrptr, idx, NULL), IPP_PRNT_PAUSED,
                        strlen(IPP_PRNT_PAUSED)) == 0) {
                    printer_state_dyn->printer_reasons[reason_idx++] = PRINT_STATUS_UNKNOWN;
                }
            }
        }  // end of reasons loop
    }
}

static void print_col(ipp_t *col) {
    int i;
    ipp_attribute_t *attr;

    LOGD("{");
    for (attr = ippFirstAttribute(col); attr; attr = ippNextAttribute(col)) {
        switch (ippGetValueTag(attr)) {
            case IPP_TAG_INTEGER:
            case IPP_TAG_ENUM:
                for (i = 0; i < ippGetCount(attr); i++) {
                    LOGD("  %s(%s%s)= %d ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)), ippGetInteger(attr, i));
                }
                break;
            case IPP_TAG_BOOLEAN:
                for (i = 0; i < ippGetCount(attr); i++) {
                    if (ippGetBoolean(attr, i)) {
                        LOGD("  %s(%s%s)= true ", ippGetName(attr),
                                ippGetCount(attr) > 1 ? "1setOf " : "",
                                ippTagString(ippGetValueTag(attr)));
                    } else {
                        LOGD("  %s(%s%s)= false ", ippGetName(attr),
                                ippGetCount(attr) > 1 ? "1setOf " : "",
                                ippTagString(ippGetValueTag(attr)));
                    }
                }
                break;
            case IPP_TAG_NOVALUE:
                LOGD("  %s(%s%s)= novalue", ippGetName(attr),
                        ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)));
                break;
            case IPP_TAG_RANGE:
                for (i = 0; i < ippGetCount(attr); i++) {
                    int lower, upper;
                    lower = ippGetRange(attr, i, &upper);
                    LOGD("  %s(%s%s)= %d-%d ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)), lower, upper);
                }
                break;
            case IPP_TAG_RESOLUTION:
                for (i = 0; i < ippGetCount(attr); i++) {
                    ipp_res_t units;
                    int xres, yres;
                    xres = ippGetResolution(attr, i, &yres, &units);
                    LOGD("  %s(%s%s)= %dx%d%s ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)), xres, yres,
                            units == IPP_RES_PER_INCH ? "dpi" : "dpc");
                }
                break;
            case IPP_TAG_STRING:
            case IPP_TAG_TEXT:
            case IPP_TAG_NAME:
            case IPP_TAG_KEYWORD:
            case IPP_TAG_CHARSET:
            case IPP_TAG_URI:
            case IPP_TAG_MIMETYPE:
            case IPP_TAG_LANGUAGE:
                for (i = 0; i < ippGetCount(attr); i++) {
                    LOGD("  %s(%s%s)= \"%s\" ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)), ippGetString(attr, i, NULL));
                }
                break;
            case IPP_TAG_TEXTLANG:
            case IPP_TAG_NAMELANG:
                for (i = 0; i < ippGetCount(attr); i++) {
                    const char *charset;
                    const char *text;
                    text = ippGetString(attr, i, &charset);
                    LOGD("  %s(%s%s)= \"%s\",%s ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)), text, charset);
                }
                break;
            case IPP_TAG_BEGIN_COLLECTION:
                for (i = 0; i < ippGetCount(attr); i++) {
                    print_col(ippGetCollection(attr, i));
                }
                break;
            default:
                break;
        }
    }
    LOGD("}");
}

void print_attr(ipp_attribute_t *attr) {
    int i;

    if (ippGetName(attr) == NULL) {
        return;
    }

    switch (ippGetValueTag(attr)) {
        case IPP_TAG_INTEGER:
        case IPP_TAG_ENUM:
            for (i = 0; i < ippGetCount(attr); i++) {
                LOGD("%s (%s%s) = %d ", ippGetName(attr), ippGetCount(attr) > 1 ? "1setOf " : "",
                        ippTagString(ippGetValueTag(attr)), ippGetInteger(attr, i));
            }
            break;
        case IPP_TAG_BOOLEAN:
            for (i = 0; i < ippGetCount(attr); i++) {
                if (ippGetBoolean(attr, i)) {
                    LOGD("%s (%s%s) = true ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)));
                } else {
                    LOGD("%s (%s%s) = false ", ippGetName(attr),
                            ippGetCount(attr) > 1 ? "1setOf " : "",
                            ippTagString(ippGetValueTag(attr)));
                }
            }
            break;
        case IPP_TAG_NOVALUE:
            LOGD("%s (%s%s) = novalue", ippGetName(attr),
                    ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)));
            break;
        case IPP_TAG_RANGE:
            for (i = 0; i < ippGetCount(attr); i++) {
                int lower, upper;
                lower = ippGetRange(attr, i, &upper);
                LOGD("%s (%s%s) = %d-%d ", ippGetName(attr), ippGetCount(attr) > 1 ? "1setOf " : "",
                        ippTagString(ippGetValueTag(attr)), lower, upper);
            }
            break;
        case IPP_TAG_RESOLUTION:
            for (i = 0; i < ippGetCount(attr); i++) {
                ipp_res_t units;
                int xres, yres;
                xres = ippGetResolution(attr, i, &yres, &units);
                LOGD("%s (%s%s) = %dx%d%s ", ippGetName(attr),
                        ippGetCount(attr) > 1 ? "1setOf " : "",
                        ippTagString(ippGetValueTag(attr)), xres, yres,
                        units == IPP_RES_PER_INCH ? "dpi" : "dpc");
            }
            break;
        case IPP_TAG_STRING:
        case IPP_TAG_TEXT:
        case IPP_TAG_NAME:
        case IPP_TAG_KEYWORD:
        case IPP_TAG_CHARSET:
        case IPP_TAG_URI:
        case IPP_TAG_MIMETYPE:
        case IPP_TAG_LANGUAGE:
            for (i = 0; i < ippGetCount(attr); i++) {
                LOGD("%s (%s%s) = \"%s\" ", ippGetName(attr),
                        ippGetCount(attr) > 1 ? "1setOf " : "",
                        ippTagString(ippGetValueTag(attr)), ippGetString(attr, i, NULL));
            }
            break;
        case IPP_TAG_TEXTLANG:
        case IPP_TAG_NAMELANG:
            for (i = 0; i < ippGetCount(attr); i++) {
                const char *charset;
                const char *text;
                text = ippGetString(attr, i, &charset);
                LOGD("%s (%s%s) = \"%s\",%s ", ippGetName(attr),
                        ippGetCount(attr) > 1 ? "1setOf " : "",
                        ippTagString(ippGetValueTag(attr)), text, charset);
            }
            break;

        case IPP_TAG_BEGIN_COLLECTION:
            for (i = 0; i < ippGetCount(attr); i++) {
                LOGD("%s (%s%s): IPP_TAG_BEGIN_COLLECTION", ippGetName(attr),
                        ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)));
                print_col(ippGetCollection(attr, i));
            }
            LOGD("%s (%s%s): IPP_TAG_END_COLLECTION", ippGetName(attr),
                    ippGetCount(attr) > 1 ? "1setOf " : "", ippTagString(ippGetValueTag(attr)));
            break;

        default:
            break;
    }
}

void parse_IPPVersions(ipp_t *response, ipp_version_supported_t *ippVersions) {
    int i;
    ipp_attribute_t *attrptr;
    char ipp10[] = "1.0";
    char ipp11[] = "1.1";
    char ipp20[] = "2.0";
    LOGD(" Entered IPPVersions");
    if (ippVersions != NULL) {
        memset(ippVersions, 0, sizeof(ipp_version_supported_t));
        LOGD(" in get_supportedIPPVersions");
        attrptr = ippFindAttribute(response, "ipp-versions-supported", IPP_TAG_KEYWORD);
        if (attrptr != NULL) {
            LOGD(" in get_supportedIPPVersions: %d", ippGetCount(attrptr));
            for (i = 0; i < ippGetCount(attrptr); i++) {
                if (strcmp(ipp10, ippGetString(attrptr, i, NULL)) == 0) {
                    ippVersions->supportsIpp10 = 1;
                } else if (strcmp(ipp11, ippGetString(attrptr, i, NULL)) == 0) {
                    ippVersions->supportsIpp11 = 1;
                } else if (strcmp(ipp20, ippGetString(attrptr, i, NULL)) == 0) {
                    ippVersions->supportsIpp20 = 1;
                } else {
                    LOGD("found another ipp version. %s", ippGetString(attrptr, i, NULL));
                }
            }
        }
    }
}

const char *mapDFMediaToIPPKeyword(media_size_t media_size) {
    int i;
    for (i = 0; i < SUPPORTED_MEDIA_SIZE_COUNT; i++) {
        if (SupportedMediaSizes[i].media_size == (media_size_t) media_size) {
            return (SupportedMediaSizes[i].PWGName);
        }
    }
    return (SupportedMediaSizes[0].PWGName);
}

int ipp_find_media_size(const char *ipp_media_keyword, media_size_t *media_size) {
    int i;
    LOGD("ipp_find_media_size entry is %s", ipp_media_keyword);
    for (i = 0; i < SUPPORTED_MEDIA_SIZE_COUNT; i++) {
        if (strcmp(SupportedMediaSizes[i].PWGName, ipp_media_keyword) == 0) {
            LOGD(" mediaArraySize: match string  %s  PT_size: %d",
                    SupportedMediaSizes[i].PWGName, SupportedMediaSizes[i].media_size);
            break;
        }
    }
    if (i < SUPPORTED_MEDIA_SIZE_COUNT) {
        *media_size = SupportedMediaSizes[i].media_size;
        return i;
    } else {
        return -1;
    }
    return -1;
}

void parse_getMediaSupported(ipp_t *response, media_supported_t *media_supported) {
    int i;
    ipp_attribute_t *attrptr;
    int sizes_idx = 0;
    LOGD(" Entered getMediaSupported");

    media_size_t media_sizeTemp;
    int idx = 0;

    if ((attrptr = ippFindAttribute(response, "media-supported", IPP_TAG_KEYWORD)) != NULL) {
        LOGD("media-supported  found; number of values %d", ippGetCount(attrptr));
        for (i = 0; i < ippGetCount(attrptr); i++) {
            idx = ipp_find_media_size(ippGetString(attrptr, i, NULL), &media_sizeTemp);

            // Modified since anytime the find media size returned 0 it could either mean
            // NOT found or na_letter.
            if (idx >= 0) {
                media_supported->media_size[sizes_idx] = media_sizeTemp;
                media_supported->idxKeywordTranTable[sizes_idx] = idx;
                sizes_idx++;
            }
        }
    } else {
        LOGD("media-supported not found");
    }
}

static void get_supportedPrinterResolutions(ipp_attribute_t *attrptr,
        printer_capabilities_t *capabilities) {
    int idx = 0;
    int i;
    for (i = 0; i < ippGetCount(attrptr); i++) {
        ipp_res_t units;
        int xres, yres;
        xres = ippGetResolution(attrptr, i, &yres, &units);
        if (units == IPP_RES_PER_INCH) {
            if ((idx < MAX_RESOLUTIONS_SUPPORTED) && (xres == yres)) {
                capabilities->supportedResolutions[idx] = xres;
                idx++;
            }
        }
    }
    capabilities->numSupportedResolutions = idx;
}

void getResourceFromURI(const char *uri, char *resource, int resourcelen) {
    char scheme[1024];
    char username[1024];
    char host[1024];
    int port;
    httpSeparateURI(0, uri, scheme, 1024, username, 1024, host, 1024, &port, resource, resourcelen);
}

/*
 * Add a new media type to a printer's collection of supported media types
 */
static void addMediaType(printer_capabilities_t *capabilities, media_type_t mediaType) {
    int index;
    for (index = 0; index < capabilities->numSupportedMediaTypes; index++) {
        // Skip if already present
        if (capabilities->supportedMediaTypes[index] == mediaType) return;
    }

    // Add if not found and not too many
    if (capabilities->numSupportedMediaTypes < MAX_MEDIA_TYPES_SUPPORTED) {
        capabilities->supportedMediaTypes[capabilities->numSupportedMediaTypes++] = mediaType;
    } else {
        LOGI("Hit MAX_MEDIA_TYPES_SUPPORTED while adding %d", mediaType);
    }
}

void parse_printerAttributes(ipp_t *response, printer_capabilities_t *capabilities) {
    int i, j;
    ipp_attribute_t *attrptr;

    LOGD("Entered parse_printerAttributes");

    media_supported_t media_supported;
    for (i = 0; i <= PAGE_STATUS_MAX - 1; i++) {
        media_supported.media_size[i] = 0;
    }
    parse_getMediaSupported(response, &media_supported);

    parse_printerUris(response, capabilities);

    LOGD("Media Supported: ");
    int idx = 0;
    capabilities->numSupportedMediaTypes = 0;
    for (i = 0; i <= PAGE_STATUS_MAX - 1; i++) {
        if (media_supported.media_size[i] != 0) {
            capabilities->supportedMediaSizes[capabilities->numSupportedMediaSizes++] =
                    media_supported.media_size[i];
            idx = media_supported.idxKeywordTranTable[i];
            LOGD(" i %d, \tPT_Size: %d  \tidx %d \tKeyword: %s", i, media_supported.media_size[i],
                    idx, SupportedMediaSizes[idx].PWGName);
        }
    }

    if ((attrptr = ippFindAttribute(response, "printer-dns-sd-name", IPP_TAG_NAME)) != NULL) {
        strlcpy(capabilities->name, ippGetString(attrptr, 0, NULL), sizeof(capabilities->name));
    }

    if (!capabilities->name[0]) {
        if ((attrptr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL) {
            strlcpy(capabilities->name, ippGetString(attrptr, 0, NULL), sizeof(capabilities->name));
        }
    }

    if (!capabilities->name[0]) {
        if ((attrptr = ippFindAttribute(response, "printer-name", IPP_TAG_TEXT)) != NULL) {
            strlcpy(capabilities->name, ippGetString(attrptr, 0, NULL), sizeof(capabilities->name));
        }
    }

    if ((attrptr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) {
        strlcpy(capabilities->make, ippGetString(attrptr, 0, NULL), sizeof(capabilities->make));
    }

    if ((attrptr = ippFindAttribute(response, "printer-uuid", IPP_TAG_URI)) != NULL) {
        strlcpy(capabilities->uuid, ippGetString(attrptr, 0, NULL), sizeof(capabilities->uuid));
    }

    if ((attrptr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL) {
        strlcpy(capabilities->location, ippGetString(attrptr, 0, NULL),
                sizeof(capabilities->location));
    }

    if ((attrptr = ippFindAttribute(response, "media-default", IPP_TAG_KEYWORD)) != NULL) {
        strlcpy(capabilities->mediaDefault, ippGetString(attrptr, 0, NULL),
                sizeof(capabilities->mediaDefault));
    }

    if ((attrptr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL) {
        if (ippGetBoolean(attrptr, 0)) {
            capabilities->color = 1;
        }
    }
    if ((attrptr = ippFindAttribute(response, "copies-supported", IPP_TAG_RANGE)) != NULL) {
        int upper = 0;
        for (i = 0; i < ippGetCount(attrptr); i++) {
            ippGetRange(attrptr, i, &upper);
        }
        if (upper > 1) {
            capabilities->canCopy = 1;
        }
    }
    if ((attrptr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcmp("color", ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->color = 1;
            }
        }
    }
    if ((attrptr = ippFindAttribute(response, "print-quality-supported", IPP_TAG_ENUM)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr) && capabilities->numSupportedQuality
                < MAX_QUALITY_SUPPORTED; i++) {
            LOGD("print-quality-supported: %d", ippGetInteger(attrptr, i));
            capabilities->supportedQuality[capabilities->numSupportedQuality++] =
                ippGetInteger(attrptr, i);
        }
    }

    char imagePCLm[] = "application/PCLm";
    char imagePWG[] = "image/pwg-raster";
    char imagePDF[] = "image/pdf";
    char applicationPDF[] = "application/pdf";

    if ((attrptr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE))
            != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcmp(imagePDF, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->canPrintPDF = 1;
            } else if (strcmp(applicationPDF, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->canPrintPDF = 1;
            } else if (strcmp(imagePCLm, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->canPrintPCLm = 1;
            } else if (strcmp(applicationPDF, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->canPrintPDF = 1;
            } else if (strcmp(imagePWG, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->canPrintPWG = 1;
            }
        }
    }

    if ((attrptr = ippFindAttribute(response, "sides-supported", IPP_TAG_KEYWORD)) != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcmp(IPP_SIDES_TWO_SIDED_SHORT_EDGE, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->duplex = 1;
            } else if (strcmp(IPP_SIDES_TWO_SIDED_LONG_EDGE, ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->duplex = 1;
            }
        }
    }

    // Look up supported media types
    capabilities->numSupportedMediaTypes = 0;
    if (((attrptr = ippFindAttribute(response, "media-type-supported", IPP_TAG_KEYWORD)) != NULL)
            || ((attrptr = ippFindAttribute(response, "media-type-supported", IPP_TAG_NAME))
                    != NULL)) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcasestr(ippGetString(attrptr, i, NULL), "photographic-glossy")) {
                addMediaType(capabilities, MEDIA_PHOTO_GLOSSY);
            } else if (strcasestr(ippGetString(attrptr, i, NULL), "photo")) {
                addMediaType(capabilities, MEDIA_PHOTO);
            } else if (strcasestr(ippGetString(attrptr, i, NULL), "stationery")) {
                addMediaType(capabilities, MEDIA_PLAIN);
            }
        }
    }

    if (capabilities->numSupportedMediaTypes == 0) {
        // If no recognized media types were found, fall back to all 3 just in case
        addMediaType(capabilities, MEDIA_PLAIN);
        addMediaType(capabilities, MEDIA_PHOTO);
        addMediaType(capabilities, MEDIA_PHOTO_GLOSSY);
    }

    capabilities->numSupportedResolutions = 0;
    // only appears that SMM supports the pclm-source-resolution-supported attribute
    // if that is not present, use the printer-resolution-supported attribute to determine
    // if 300DPI is supported
    if ((attrptr = ippFindAttribute(response, "pclm-source-resolution-supported",
            IPP_TAG_RESOLUTION)) != NULL) {
        get_supportedPrinterResolutions(attrptr, capabilities);
    } else if ((attrptr = ippFindAttribute(response, "printer-resolution-supported",
            IPP_TAG_RESOLUTION)) != NULL) {
        get_supportedPrinterResolutions(attrptr, capabilities);
    }

    char ipp10[] = "1.0";
    char ipp11[] = "1.1";
    char ipp20[] = "2.0";

    if ((attrptr = ippFindAttribute(response, "ipp-versions-supported", IPP_TAG_KEYWORD)) != NULL) {
        unsigned char supportsIpp20 = 0;
        unsigned char supportsIpp11 = 0;
        unsigned char supportsIpp10 = 0;

        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcmp(ipp10, ippGetString(attrptr, i, NULL)) == 0) {
                supportsIpp10 = 1;
            } else if (strcmp(ipp11, ippGetString(attrptr, i, NULL)) == 0) {
                supportsIpp11 = 1;
            } else if (strcmp(ipp20, ippGetString(attrptr, i, NULL)) == 0) {
                supportsIpp20 = 1;
            } else {
                LOGD("found another ipp version. %s", ippGetString(attrptr, i, NULL));
            }
            if (supportsIpp20) {
                capabilities->ippVersionMajor = 2;
                capabilities->ippVersionMinor = 0;
            } else if (supportsIpp11) {
                capabilities->ippVersionMajor = 1;
                capabilities->ippVersionMinor = 1;
            } else if (supportsIpp10) {
                capabilities->ippVersionMajor = 1;
                capabilities->ippVersionMinor = 0;
            } else {
                // default to 1.0
                capabilities->ippVersionMajor = 1;
                capabilities->ippVersionMinor = 0;
            }
        }
    }

    char epcl10[] = "1.0";
    if ((attrptr = ippFindAttribute(response, "epcl-version-supported", IPP_TAG_KEYWORD)) != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            LOGD("setting epcl_ipp_version (KEYWORD) %s", ippGetString(attrptr, i, NULL));

            // substring match because different devices implemented spec differently
            if (strstr(ippGetString(attrptr, i, NULL), epcl10) != NULL) {
                LOGD("setting epcl_ipp_version = 1");
                capabilities->ePclIppVersion = 1;
            }
        }
    }

    if ((attrptr = ippFindAttribute(response, "epcl-version-supported", IPP_TAG_TEXT)) != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            LOGD("setting epcl_ipp_verion (TEXT) %s", ippGetString(attrptr, i, NULL));

            // substring match because different devices implemented spec differently
            if (strstr(ippGetString(attrptr, i, NULL), epcl10) != NULL) {
                LOGD("setting epcl_ipp_verion = 1");
                capabilities->ePclIppVersion = 1;
            }
        }
    }

    if ((attrptr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            LOGD("Gathering margins supported");

            ipp_t *collection = ippGetCollection(attrptr, i);

            for (j = 0, attrptr = ippFirstAttribute(collection);
                    (j < 4) && (attrptr != NULL); attrptr = ippNextAttribute(collection)) {
                if (strcmp("media-top-margin", ippGetName(attrptr)) == 0) {
                    capabilities->printerTopMargin = ippGetInteger(attrptr, 0);
                } else if (strcmp("media-bottom-margin", ippGetName(attrptr)) == 0) {
                    capabilities->printerBottomMargin = ippGetInteger(attrptr, 0);
                } else if (strcmp("media-left-margin", ippGetName(attrptr)) == 0) {
                    capabilities->printerLeftMargin = ippGetInteger(attrptr, 0);
                } else if (strcmp("media-right-margin", ippGetName(attrptr)) == 0) {
                    capabilities->printerRightMargin = ippGetInteger(attrptr, 0);
                }
            }
        }
    }

    if ((attrptr = ippFindAttribute(response, "media-size-name", IPP_TAG_KEYWORD)) != NULL) {
        capabilities->isMediaSizeNameSupported = true;
    } else {
        capabilities->isMediaSizeNameSupported = false;
    }

    // is strip length supported? if so, stored in capabilities
    if ((attrptr = ippFindAttribute(response, "pclm-strip-height-preferred",
            IPP_TAG_INTEGER)) != NULL) {
        LOGD("pclm-strip-height-preferred=%d", ippGetInteger(attrptr, 0));

        // if the strip height is 0, the device wants us to send the entire page in one band
        // (according to ePCL spec). Since our code doesn't currently support generating an entire
        // page in one band, set the strip height to the default value every device *should* support
        // also, for some reason our code crashes when it attempts to generate strips at 512 or
        // above. Therefore, limiting the upper bound strip height to 256
        if (ippGetInteger(attrptr, 0) == 0 || ippGetInteger(attrptr, 0) > 256) {
            capabilities->stripHeight = STRIPE_HEIGHT;
        } else {
            capabilities->stripHeight = ippGetInteger(attrptr, 0);
        }
    } else {
        capabilities->stripHeight = STRIPE_HEIGHT;
    }

    // what is the preferred compression method - jpeg, flate, rle
    if ((attrptr = ippFindAttribute(response, "pclm-compression-method-preferred",
            IPP_TAG_KEYWORD)) != NULL) {
        LOGD("pclm-compression-method-preferred=%s", ippGetString(attrptr, 0, NULL));
    }

    // is device able to rotate back page for duplex jobs? (assume PCLM and PWG are similar)
    capabilities->canRotateDuplexBackPage = 0;
    if ((attrptr = ippFindAttribute(response, "pclm-raster-back-side", IPP_TAG_KEYWORD)) == NULL) {
        attrptr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD);
    }
    if (attrptr != NULL && strcmp(ippGetString(attrptr, 0, NULL), "rotated") != 0) {
        LOGD("Device can rotate back page for duplex jobs.");
        capabilities->canRotateDuplexBackPage = 1;
    }

    // look for full-bleed supported by looking for 0 on all margins
    bool topsupported = false, bottomsupported = false, rightsupported = false,
            leftsupported = false;
    if ((attrptr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (ippGetInteger(attrptr, i) == 0) {
                LOGD("Top Margin Supported");
                topsupported = true;
                break;
            }
        }
    }
    if ((attrptr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (ippGetInteger(attrptr, i) == 0) {
                LOGD("Bottom Margin Supported");
                bottomsupported = true;
                break;
            }
        }
    }
    if ((attrptr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (ippGetInteger(attrptr, i) == 0) {
                LOGD("Right Margin Supported");
                rightsupported = true;
                break;
            }
        }
    }
    if ((attrptr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) !=
            NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (ippGetInteger(attrptr, i) == 0) {
                LOGD("Left Margin Supported");
                leftsupported = true;
                break;
            }
        }
    }

    if (topsupported && bottomsupported && rightsupported && leftsupported) {
        LOGD("full-bleed is supported");
        capabilities->borderless = 1;
    } else {
        LOGD("full-bleed is NOT supported");
    }

    if ((attrptr = ippFindAttribute(response, "printer-device-id", IPP_TAG_TEXT)) != NULL) {
        if (strstr(ippGetString(attrptr, 0, NULL), "PCL3GUI") != NULL) {
            capabilities->inkjet = 1;
        }
    } else if (capabilities->borderless == 1) {
        capabilities->inkjet = 1;
    }

    // determine if device prints pages face-down
    capabilities->faceDownTray = 1;
    if ((attrptr = ippFindAttribute(response, "output-bin-supported", IPP_TAG_KEYWORD)) != NULL) {
        if (strstr(ippGetString(attrptr, 0, NULL), "face-up") != NULL) {
            capabilities->faceDownTray = 0;
        }
    }
    if ((attrptr = ippFindAttribute(response, "printer-output-tray", IPP_TAG_STRING)) != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            int length = 0;
            const char *tray_str = ippGetOctetString(attrptr, i, &length);
            if (strstr(tray_str, "faceUp") != NULL) {
                capabilities->faceDownTray = 0;
            }
        }
    }

    // Determine supported document format details
    if ((attrptr = ippFindAttribute(response, "document-format-details-supported",
            IPP_TAG_KEYWORD)) != NULL) {
        for (i = 0; i < ippGetCount(attrptr); i++) {
            if (strcmp("document-source-application-name", ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->docSourceAppName = 1;
            } else if (
                    strcmp("document-source-application-version", ippGetString(attrptr, i, NULL)) ==
                            0) {
                capabilities->docSourceAppVersion = 1;
            } else if (strcmp("document-source-os-name", ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->docSourceOsName = 1;
            } else if (strcmp("document-source-os-version", ippGetString(attrptr, i, NULL)) == 0) {
                capabilities->docSourceOsVersion = 1;
            }
        }
    }
    debuglist_printerCapabilities(capabilities);
}

// Used in parse_printerUris
#define MAX_URIS 10
typedef struct {
    const char *uri;
    int valid;
} parsed_uri_t;

static void parse_printerUris(ipp_t *response, printer_capabilities_t *capabilities) {
    ipp_attribute_t *attrptr;
    int i;
    parsed_uri_t uris[MAX_URIS] = {0};

    if ((attrptr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) {
        for (i = 0; i < MIN(ippGetCount(attrptr), MAX_URIS); i++) {
            uris[i].uri = ippGetString(attrptr, i, NULL);
            uris[i].valid = true;
        }
    }

    // If authentication is required by any URI, mark it invalid
    if ((attrptr = ippFindAttribute(response, "uri-authentication-supported", IPP_TAG_KEYWORD))
            != NULL) {
        for (i = 0; i < MIN(ippGetCount(attrptr), MAX_URIS); i++) {
            // Allow "none" and "requesting-user-name" only
            if (strcmp("none", ippGetString(attrptr, i, NULL)) != 0 &&
                    strcmp("requesting-user-name", ippGetString(attrptr, i, NULL)) != 0) {
                LOGD("parse_printerUris %s invalid because auth=%s", uris[i].uri,
                        ippGetString(attrptr, i, NULL));
                uris[i].valid = false;
            }
        }
    }

    // Find a valid URI and copy it into place.
    for (i = 0; i < MAX_URIS; i++) {
        // Copy if the URI is valid and we haven't yet discovered ipps
        if (uris[i].valid && strncmp(capabilities->printerUri, "ipps://", 7) != 0) {
            LOGD("parse_printerUris found %s", uris[i].uri);
            strlcpy(capabilities->printerUri, uris[i].uri, sizeof(capabilities->printerUri));
        }
    }
}

void debuglist_printerCapabilities(printer_capabilities_t *capabilities) {
    LOGD("printer make: %s", capabilities->make);
    LOGD("printer default media: %s", capabilities->mediaDefault);
    LOGD("canPrintPDF: %d", capabilities->canPrintPDF);
    LOGD("duplex: %d", capabilities->duplex);
    LOGD("canRotateDuplexBackPage: %d", capabilities->canRotateDuplexBackPage);
    LOGD("color: %d", capabilities->color);
    LOGD("canCopy: %d", capabilities->canCopy);
    LOGD("ippVersionMajor: %d", capabilities->ippVersionMajor);
    LOGD("ippVersionMinor: %d", capabilities->ippVersionMinor);
    LOGD("strip height: %d", capabilities->stripHeight);
    LOGD("faceDownTray: %d", capabilities->faceDownTray);
}

void debuglist_printerStatus(printer_state_dyn_t *printer_state_dyn) {
    const char *decoded = "unknown";
    if (printer_state_dyn->printer_status == PRINT_STATUS_INITIALIZING) {
        decoded = "Initializing";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_SHUTTING_DOWN) {
        decoded = "Shutting Down";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_UNABLE_TO_CONNECT) {
        decoded = "Unable To Connect";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_UNKNOWN) {
        decoded = "Unknown";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_OFFLINE) {
        decoded = "Offline";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_IDLE) {
        decoded = "Idle";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_PRINTING) {
        decoded = "Printing";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_OUT_OF_PAPER) {
        decoded = "Out Of Paper";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_OUT_OF_INK) {
        decoded = "Out Of Ink";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_JAMMED) {
        decoded = "Jammed";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_DOOR_OPEN) {
        decoded = "Door Open";
    } else if (printer_state_dyn->printer_status == PRINT_STATUS_SVC_REQUEST) {
        decoded = "Service Request";
    }
    LOGD("printer status: %d (%s)", printer_state_dyn->printer_status, decoded);

    int idx = 0;
    for (idx = 0; idx < (PRINT_STATUS_MAX_STATE + 1); idx++) {
        if (PRINT_STATUS_MAX_STATE != printer_state_dyn->printer_reasons[idx]) {
            LOGD("printer_reasons (%d): %d", idx, printer_state_dyn->printer_reasons[idx]);
        }
    }
}

/*
 * Handle server certificate information.
 */
static int ipp_server_cert_cb(http_t *http, void *tls, cups_array_t *certs, void *user_data) {
    wprint_connect_info_t *connect_info = (wprint_connect_info_t *)user_data;
    int error = 0;
    if (connect_info->validate_certificate) {
        http_credential_t *credential = cupsArrayFirst(certs);
        if (credential) {
            LOGD("ipp_server_cert_cb: validate_certificate (len=%d)", credential->datalen);
            error = connect_info->validate_certificate(connect_info, credential->data, credential->datalen);
        }
    }
    return error;
}

http_t *ipp_cups_connect(const wprint_connect_info_t *connect_info, char *printer_uri,
        unsigned int uriLength) {
    const char *uri_path;
    http_t *curl_http = NULL;

    cupsSetServerCertCB(ipp_server_cert_cb, (void *)connect_info);

    if ((connect_info->uri_path == NULL) || (strlen(connect_info->uri_path) == 0)) {
        uri_path = DEFAULT_IPP_URI_RESOURCE;
    } else {
        uri_path = connect_info->uri_path;
    }

    int ippPortNumber = ((connect_info->port_num == IPP_PORT) ? ippPort() : connect_info->port_num);

    if (strstr(connect_info->uri_scheme,IPPS_PREFIX) != NULL) {
        curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPTION_ALWAYS);

        // If ALWAYS doesn't work, fall back to REQUIRED
        if (curl_http == NULL) {
            curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPT_REQUIRED);
        }
    } else {
        curl_http = httpConnectEncrypt(connect_info->printer_addr, ippPortNumber, HTTP_ENCRYPTION_IF_REQUESTED);
    }

    httpSetTimeout(curl_http, (double)connect_info->timeout / 1000, NULL, 0);
    httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, uriLength, connect_info->uri_scheme, NULL,
            connect_info->printer_addr, ippPortNumber, uri_path);

    if (curl_http == NULL) {
        LOGD("ipp_cups_connect failed addr=%s port=%d", connect_info->printer_addr, ippPortNumber);
    }

    cupsSetServerCertCB(NULL, NULL);
    return curl_http;
}

/*
 * Send a request using cupsSendRequest(). Loop if we get NULL or CONTINUE. Does not delete
 * the request.
 */
static ipp_t *ippSendRequest(http_t *http, ipp_t *request, char *resource) {
    ipp_t *response = NULL;
    http_status_t result;
    bool retry;

    do {
        retry = false;
        result = cupsSendRequest(http, request, resource, ippLength(request));
        if (result != HTTP_ERROR) {
            response = cupsGetResponse(http, resource);
            result = httpGetStatus(http);
        }

        if (result == HTTP_CONTINUE && response == NULL) {
            // We need to retry when this happens.
            LOGD("ippSendRequest: (Continue with NULL response) Retry");
            retry = true;
        } else if (result == HTTP_ERROR || result >= HTTP_BAD_REQUEST) {
            _cupsSetHTTPError(result);
            break;
        }

        if (http->state != HTTP_WAITING) {
            httpFlush(http);
        }
    } while (retry);

    return response;
}

/*
 * Call ippDoCupsIORequest, repeating if a failure occurs based on failure conditions, and
 * returning the response (or NULL if it failed).
 *
 * Does not free the request, and the caller must call ippDelete to free any valid response.
 */
ipp_t *ipp_doCupsRequest(http_t *http, ipp_t *request, char *http_resource, char *printer_uri) {
    ipp_status_t ipp_status;
    ipp_t *response = NULL;
    int service_unavailable_retry_count = 0;
    int bad_request_retry_count = 0;
    int internal_error_retry_count = 0;
    ipp_version_state ipp_version_supported = IPP_VERSION_RESOLVED;

    // Fail if any of these parameters are NULL
    if (http == NULL || request == NULL || http_resource == NULL || printer_uri == NULL) {
        return NULL;
    }

    do {
        // Give up immediately if wprint is done.
        if (!wprintIsRunning()) return NULL;

        // This is a no-op until we hit the error IPP_VERSION_NOT_SUPPORTED and retry.
        if (set_ipp_version(request, printer_uri, http, ipp_version_supported) != 0) {
            // We tried to find the correct IPP version by doing a series of get attribute
            // requests but they all failed... we give up.
            LOGE("ipp_doCupsRequest: set_ipp_version!=0, version not set");
            break;
        }

        response = ippSendRequest(http, request, http_resource);
        if (response == NULL) {
            ipp_status = cupsLastError();
            if (ipp_status == IPP_INTERNAL_ERROR || ipp_status == HTTP_ERROR) {
                internal_error_retry_count++;
                if (internal_error_retry_count > IPP_INTERNAL_ERROR_MAX_RETRIES) {
                    break;
                }

                LOGE("ipp_doCupsRequest: %s %d received, retry %d of %d",
                        printer_uri, ipp_status, internal_error_retry_count,
                        IPP_INTERNAL_ERROR_MAX_RETRIES);
                continue;
            } else if (ipp_status == IPP_SERVICE_UNAVAILABLE) {
                service_unavailable_retry_count++;
                if (service_unavailable_retry_count > IPP_SERVICE_ERROR_MAX_RETRIES) {
                    break;
                }

                LOGE("ipp_doCupsRequest: %s IPP_SERVICE_UNAVAILABLE received, retrying %d of %d",
                        printer_uri, service_unavailable_retry_count,
                        IPP_SERVICE_ERROR_MAX_RETRIES);
                continue;
            } else if (ipp_status == IPP_BAD_REQUEST) {
                bad_request_retry_count++;
                if (bad_request_retry_count > IPP_BAD_REQUEST_MAX_RETRIES) {
                    break;
                }

                LOGD("ipp_doCupsRequest: %s IPP_BAD_REQUEST received. retry (%d) of (%d)",
                        printer_uri, bad_request_retry_count, IPP_BAD_REQUEST_MAX_RETRIES);
                continue;
            } else if (ipp_status == IPP_NOT_FOUND) {
                LOGE("ipp_doCupsRequest: %s IPP_NOT_FOUND received.", printer_uri);
                break;
            }
        } else {
            ipp_status = cupsLastError();
            if (ipp_status == IPP_BAD_REQUEST) {
                bad_request_retry_count++;
                LOGE("ipp_doCupsRequest: %s IPP_BAD_REQUEST received. retry (%d) of (%d)",
                        printer_uri, bad_request_retry_count, IPP_BAD_REQUEST_MAX_RETRIES);
                if (bad_request_retry_count > IPP_BAD_REQUEST_MAX_RETRIES) {
                    break;
                }

                ippDelete(response);
                response = NULL;
                continue;
            } else if (ipp_status == IPP_VERSION_NOT_SUPPORTED) {
                ipp_version_supported = IPP_VERSION_UNSUPPORTED;
                ippDelete(response);
                response = NULL;
                continue;
            }
        }
        break;
    } while (1);

    return response;
}