/****************************************************************************
**
** Copyright (C) 2014 John Layt <jlayt@kde.org>
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qcocoaprintdevice.h"

#if QT_CONFIG(mimetype)
#include <QtCore/qmimedatabase.h>
#endif
#include <qdebug.h>

QT_BEGIN_NAMESPACE

#ifndef QT_NO_PRINTER

// The CUPS PPD APIs were deprecated in CUPS 1.6/macOS 10.8, but
// as long as we're supporting RHEL 6, which still ships CUPS 1.4
// we're not going to rewrite this, as we want to share the code
// between macOS and Linux for the CUPS-bits. See discussion in
// https://bugreports.qt.io/browse/QTBUG-56545
#pragma message "Disabling CUPS PPD deprecation warnings. This should be fixed once we drop support for RHEL6 (QTBUG-56545)"
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

static QPrint::DuplexMode macToDuplexMode(const PMDuplexMode &mode)
{
    if (mode == kPMDuplexTumble)
        return QPrint::DuplexShortSide;
    else if (mode == kPMDuplexNoTumble)
        return QPrint::DuplexLongSide;
    else // kPMDuplexNone or kPMSimplexTumble
        return QPrint::DuplexNone;
}

QCocoaPrintDevice::QCocoaPrintDevice()
    : QPlatformPrintDevice(),
      m_printer(nullptr),
      m_session(nullptr),
      m_ppd(nullptr)
{
}

QCocoaPrintDevice::QCocoaPrintDevice(const QString &id)
    : QPlatformPrintDevice(id),
      m_printer(nullptr),
      m_session(nullptr),
      m_ppd(nullptr)
{
    if (!id.isEmpty()) {
        m_printer = PMPrinterCreateFromPrinterID(id.toCFString());
        if (m_printer) {
            m_name = QString::fromCFString(PMPrinterGetName(m_printer));
            m_location = QString::fromCFString(PMPrinterGetLocation(m_printer));
            CFStringRef cfMakeAndModel;
            if (PMPrinterGetMakeAndModelName(m_printer, &cfMakeAndModel) == noErr)
                m_makeAndModel = QString::fromCFString(cfMakeAndModel);
            Boolean isRemote;
            if (PMPrinterIsRemote(m_printer, &isRemote) == noErr)
                m_isRemote = isRemote;
            if (PMCreateSession(&m_session) == noErr)
                PMSessionSetCurrentPMPrinter(m_session, m_printer);

            // No native api to query these options, need to use PPD directly, note is deprecated from 1.6 onwards
            if (openPpdFile()) {
                // Note this is if the hardware does multiple copies, not if Cups can
                m_supportsMultipleCopies = !m_ppd->manual_copies;
                // Note this is if the hardware does collation, not if Cups can
                ppd_option_t *collate = ppdFindOption(m_ppd, "Collate");
                if (collate)
                    m_supportsCollateCopies = true;
                m_supportsCustomPageSizes = m_ppd->custom_max[0] > 0 && m_ppd->custom_max[1] > 0;
                m_minimumPhysicalPageSize = QSize(m_ppd->custom_min[0], m_ppd->custom_min[1]);
                m_maximumPhysicalPageSize = QSize(m_ppd->custom_max[0], m_ppd->custom_max[1]);
                m_customMargins = QMarginsF(m_ppd->custom_margins[0], m_ppd->custom_margins[3],
                                            m_ppd->custom_margins[2], m_ppd->custom_margins[1]);
            }
        }
    }
}

QCocoaPrintDevice::~QCocoaPrintDevice()
{
    if (m_ppd)
        ppdClose(m_ppd);
    foreach (PMPaper paper, m_macPapers)
        PMRelease(paper);
    // Releasing the session appears to also release the printer
    if (m_session)
        PMRelease(m_session);
    else if (m_printer)
        PMRelease(m_printer);
}

bool QCocoaPrintDevice::isValid() const
{
    return m_printer ? true : false;
}

bool QCocoaPrintDevice::isDefault() const
{
    return PMPrinterIsDefault(m_printer);
}

QPrint::DeviceState QCocoaPrintDevice::state() const
{
    PMPrinterState state;
    if (PMPrinterGetState(m_printer, &state) == noErr) {
        if (state == kPMPrinterIdle)
            return QPrint::Idle;
        else if (state == kPMPrinterProcessing)
            return QPrint::Active;
        else if (state == kPMPrinterStopped)
            return QPrint::Error;
    }
    return QPrint::Error;
}

QPageSize QCocoaPrintDevice::createPageSize(const PMPaper &paper) const
{
    CFStringRef key;
    double width;
    double height;
    CFStringRef localizedName;
    if (PMPaperGetPPDPaperName(paper, &key) == noErr
        && PMPaperGetWidth(paper, &width) == noErr
        && PMPaperGetHeight(paper, &height) == noErr
        && PMPaperCreateLocalizedName(paper, m_printer, &localizedName) == noErr) {
        QPageSize pageSize = QPlatformPrintDevice::createPageSize(QString::fromCFString(key),QSize(width, height),
                                                                  QString::fromCFString(localizedName));
        CFRelease(localizedName);
        return pageSize;
    }
    return QPageSize();
}

void QCocoaPrintDevice::loadPageSizes() const
{
    m_pageSizes.clear();
    foreach (PMPaper paper, m_macPapers)
        PMRelease(paper);
    m_macPapers.clear();
    m_printableMargins.clear();
    CFArrayRef paperSizes;
    if (PMPrinterGetPaperList(m_printer, &paperSizes) == noErr) {
        int count = CFArrayGetCount(paperSizes);
        for (int i = 0; i < count; ++i) {
            PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(paperSizes, i)));
            QPageSize pageSize = createPageSize(paper);
            if (pageSize.isValid()) {
                m_pageSizes.append(pageSize);
                PMRetain(paper);
                m_macPapers.insert(pageSize.key(), paper);
                PMPaperMargins printMargins;
                PMPaperGetMargins(paper, &printMargins);
                m_printableMargins.insert(pageSize.key(), QMarginsF(printMargins.left, printMargins.top,
                                                                    printMargins.right, printMargins.bottom));
            }
        }
    }
    m_havePageSizes = true;
}

QPageSize QCocoaPrintDevice::defaultPageSize() const
{
    QPageSize pageSize;
    PMPageFormat pageFormat;
    PMPaper paper;
    if (PMCreatePageFormat(&pageFormat) == noErr) {
        if (PMSessionDefaultPageFormat(m_session, pageFormat) == noErr
            && PMGetPageFormatPaper(pageFormat, &paper) == noErr) {
            pageSize = createPageSize(paper);
        }
        PMRelease(pageFormat);
    }
    return pageSize;
}

QMarginsF QCocoaPrintDevice::printableMargins(const QPageSize &pageSize,
                                              QPageLayout::Orientation orientation,
                                              int resolution) const
{
    Q_UNUSED(orientation)
    Q_UNUSED(resolution)
    if (!m_havePageSizes)
        loadPageSizes();
    if (m_printableMargins.contains(pageSize.key()))
        return m_printableMargins.value(pageSize.key());
    return m_customMargins;
}

void QCocoaPrintDevice::loadResolutions() const
{
    m_resolutions.clear();
    UInt32 count;
    if (PMPrinterGetPrinterResolutionCount(m_printer, &count) == noErr) {
        // 1-based index
        for (UInt32 i = 1; i <= count; ++i) {
            PMResolution resolution;
            if (PMPrinterGetIndexedPrinterResolution(m_printer, i, &resolution) == noErr)
                m_resolutions.append(int(resolution.hRes));
        }
    }
    m_haveResolutions = true;
}

int QCocoaPrintDevice::defaultResolution() const
{
    int defaultResolution = 72;
    PMPrintSettings settings;
    if (PMCreatePrintSettings(&settings) == noErr) {
        PMResolution resolution;
        if (PMSessionDefaultPrintSettings(m_session, settings) == noErr
            && PMPrinterGetOutputResolution(m_printer, settings, &resolution) == noErr) {
            // PMPrinterGetOutputResolution usually fails with -9589 kPMKeyNotFound as not set in PPD
            defaultResolution = int(resolution.hRes);
        }
        PMRelease(settings);
    }
    // If no value returned (usually means not set in PPD) then use supported resolutions which
    // OSX will have populated with at least one default value (but why not returned by call?)
    if (defaultResolution <= 0) {
        if (!m_haveResolutions)
            loadResolutions();
        if (m_resolutions.count() > 0)
            return m_resolutions.at(0);  // First value or highest? Only likely to be one anyway.
        return 72; // TDOD More sensible default value???
    }
    return defaultResolution;
}

void QCocoaPrintDevice::loadInputSlots() const
{
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    // TODO Deal with concatenated names like Tray1Manual or Tray1_Man,
    //      will currently show as CustomInputSlot
    // TODO Deal with separate ManualFeed key
    // Try load standard PPD options first
    m_inputSlots.clear();
    if (m_ppd) {
        ppd_option_t *inputSlots = ppdFindOption(m_ppd, "InputSlot");
        if (inputSlots) {
            for (int i = 0; i < inputSlots->num_choices; ++i)
                m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[i]));
        }
        // If no result, try just the default
        if (m_inputSlots.size() == 0) {
            inputSlots = ppdFindOption(m_ppd, "DefaultInputSlot");
            if (inputSlots)
                m_inputSlots.append(QPrintUtils::ppdChoiceToInputSlot(inputSlots->choices[0]));
        }
    }
    // If still no result, just use Auto
    if (m_inputSlots.size() == 0)
        m_inputSlots.append(QPlatformPrintDevice::defaultInputSlot());
    m_haveInputSlots = true;
}

QPrint::InputSlot QCocoaPrintDevice::defaultInputSlot() const
{
    // No native api to query, use PPD directly
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    // Try load standard PPD option first
    if (m_ppd) {
        ppd_option_t *inputSlot = ppdFindOption(m_ppd, "DefaultInputSlot");
        if (inputSlot)
            return QPrintUtils::ppdChoiceToInputSlot(inputSlot->choices[0]);
        // If no result, then try a marked option
        ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "InputSlot");
        if (defaultChoice)
            return QPrintUtils::ppdChoiceToInputSlot(*defaultChoice);
    }
    // Otherwise return Auto
    return QPlatformPrintDevice::defaultInputSlot();
}

void QCocoaPrintDevice::loadOutputBins() const
{
    // No native api to query, use PPD directly
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    m_outputBins.clear();
    if (m_ppd) {
        ppd_option_t *outputBins = ppdFindOption(m_ppd, "OutputBin");
        if (outputBins) {
            for (int i = 0; i < outputBins->num_choices; ++i)
                m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[i]));
        }
        // If no result, try just the default
        if (m_outputBins.size() == 0) {
            outputBins = ppdFindOption(m_ppd, "DefaultOutputBin");
            if (outputBins)
                m_outputBins.append(QPrintUtils::ppdChoiceToOutputBin(outputBins->choices[0]));
        }
    }
    // If still no result, just use Auto
    if (m_outputBins.size() == 0)
        m_outputBins.append(QPlatformPrintDevice::defaultOutputBin());
    m_haveOutputBins = true;
}

QPrint::OutputBin QCocoaPrintDevice::defaultOutputBin() const
{
    // No native api to query, use PPD directly
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    // Try load standard PPD option first
    if (m_ppd) {
        ppd_option_t *outputBin = ppdFindOption(m_ppd, "DefaultOutputBin");
        if (outputBin)
            return QPrintUtils::ppdChoiceToOutputBin(outputBin->choices[0]);
        // If no result, then try a marked option
        ppd_choice_t *defaultChoice = ppdFindMarkedChoice(m_ppd, "OutputBin");
        if (defaultChoice)
            return QPrintUtils::ppdChoiceToOutputBin(*defaultChoice);
    }
    // Otherwise return AutoBin
    return QPlatformPrintDevice::defaultOutputBin();
}

void QCocoaPrintDevice::loadDuplexModes() const
{
    // No native api to query, use PPD directly
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    // Try load standard PPD options first
    m_duplexModes.clear();
    if (m_ppd) {
        ppd_option_t *duplexModes = ppdFindOption(m_ppd, "Duplex");
        if (duplexModes) {
            for (int i = 0; i < duplexModes->num_choices; ++i)
                m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[i].choice));
        }
        // If no result, try just the default
        if (m_duplexModes.size() == 0) {
            duplexModes = ppdFindOption(m_ppd, "DefaultDuplex");
            if (duplexModes)
                m_duplexModes.append(QPrintUtils::ppdChoiceToDuplexMode(duplexModes->choices[0].choice));
        }
    }
    // If still no result, or not added in PPD, then add None
    if (m_duplexModes.size() == 0 || !m_duplexModes.contains(QPrint::DuplexNone))
        m_duplexModes.append(QPrint::DuplexNone);
    // If have both modes, then can support DuplexAuto
    if (m_duplexModes.contains(QPrint::DuplexLongSide) && m_duplexModes.contains(QPrint::DuplexShortSide))
        m_duplexModes.append(QPrint::DuplexAuto);
    m_haveDuplexModes = true;
}

QPrint::DuplexMode QCocoaPrintDevice::defaultDuplexMode() const
{
    QPrint::DuplexMode defaultMode = QPrint::DuplexNone;
    PMPrintSettings settings;
    if (PMCreatePrintSettings(&settings) == noErr) {
        PMDuplexMode duplexMode;
        if (PMSessionDefaultPrintSettings(m_session, settings) == noErr
            && PMGetDuplex(settings, &duplexMode) == noErr) {
                defaultMode = macToDuplexMode(duplexMode);
        }
        PMRelease(settings);
    }
    return defaultMode;
}

void QCocoaPrintDevice::loadColorModes() const
{
    // No native api to query, use PPD directly
    m_colorModes.clear();
    m_colorModes.append(QPrint::GrayScale);
    if (!m_ppd || (m_ppd && m_ppd->color_device))
        m_colorModes.append(QPrint::Color);
    m_haveColorModes = true;
}

QPrint::ColorMode QCocoaPrintDevice::defaultColorMode() const
{
    // No native api to query, use PPD directly
    // NOTE: Implemented in both CUPS and Mac plugins, please keep in sync
    // Not a proper option, usually only know if supports color or not, but some
    // users known to abuse ColorModel to always force GrayScale.
    if (m_ppd && supportedColorModes().contains(QPrint::Color)) {
        ppd_option_t *colorModel = ppdFindOption(m_ppd, "DefaultColorModel");
        if (!colorModel)
            colorModel = ppdFindOption(m_ppd, "ColorModel");
        if (!colorModel || qstrcmp(colorModel->defchoice, "Gray") != 0)
            return QPrint::Color;
    }
    return QPrint::GrayScale;
}

#if QT_CONFIG(mimetype)
void QCocoaPrintDevice::loadMimeTypes() const
{
    // TODO Check how settings affect returned list
    m_mimeTypes.clear();
    QMimeDatabase db;
    PMPrintSettings settings;
    if (PMCreatePrintSettings(&settings) == noErr) {
        CFArrayRef mimeTypes;
        if (PMPrinterGetMimeTypes(m_printer, settings, &mimeTypes) == noErr) {
            int count = CFArrayGetCount(mimeTypes);
            for (int i = 0; i < count; ++i) {
                CFStringRef mimeName = static_cast<CFStringRef>(const_cast<void *>(CFArrayGetValueAtIndex(mimeTypes, i)));
                QMimeType mimeType = db.mimeTypeForName(QString::fromCFString(mimeName));
                if (mimeType.isValid())
                    m_mimeTypes.append(mimeType);
            }
        }
        PMRelease(settings);
    }
    m_haveMimeTypes = true;
}
#endif // mimetype

bool QCocoaPrintDevice::openPpdFile()
{
    if (m_ppd)
        ppdClose(m_ppd);
    m_ppd = nullptr;
    CFURLRef ppdURL = nullptr;
    char ppdPath[MAXPATHLEN];
    if (PMPrinterCopyDescriptionURL(m_printer, kPMPPDDescriptionType, &ppdURL) == noErr
        && ppdURL) {
        if (CFURLGetFileSystemRepresentation(ppdURL, true, (UInt8*)ppdPath, sizeof(ppdPath)))
            m_ppd = ppdOpenFile(ppdPath);
        CFRelease(ppdURL);
    }
    return m_ppd ? true : false;
}

PMPrinter QCocoaPrintDevice::macPrinter() const
{
    return m_printer;
}

// Returns a cached printer PMPaper, or creates and caches a new custom PMPaper
// Caller should never release a cached PMPaper!
PMPaper QCocoaPrintDevice::macPaper(const QPageSize &pageSize) const
{
    if (!m_havePageSizes)
        loadPageSizes();
    // If keys match, then is a supported size or an existing custom size
    if (m_macPapers.contains(pageSize.key()))
        return m_macPapers.value(pageSize.key());
    // For any other page size, whether custom or just unsupported, needs to be a custom PMPaper
    PMPaper paper = nullptr;
    PMPaperMargins paperMargins;
    paperMargins.left = m_customMargins.left();
    paperMargins.right = m_customMargins.right();
    paperMargins.top = m_customMargins.top();
    paperMargins.bottom = m_customMargins.bottom();
    PMPaperCreateCustom(m_printer, QCFString(pageSize.key()), QCFString(pageSize.name()),
                        pageSize.sizePoints().width(), pageSize.sizePoints().height(),
                        &paperMargins, &paper);
    m_macPapers.insert(pageSize.key(), paper);
    return paper;
}

#pragma clang diagnostic pop

#endif // QT_NO_PRINTER

QT_END_NAMESPACE
