/*
 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.print;

import java.net.URL;
import java.net.HttpURLConnection;
import java.io.OutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import sun.print.IPPPrintService;
import sun.print.CustomMediaSizeName;
import sun.print.CustomMediaTray;
import sun.print.CustomOutputBin;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OutputBin;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.Size2DSyntax;
import javax.print.attribute.Attribute;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.standard.PrinterName;


public final class CUPSPrinter  {
    private static final String debugPrefix = "CUPSPrinter>> ";
    private static final double PRINTER_DPI = 72.0;
    private boolean initialized;
    private static native String getCupsServer();
    private static native int getCupsPort();
    private static native String getCupsDefaultPrinter();
    private static native String[] getCupsDefaultPrinters();
    private static native boolean canConnect(String server, int port);
    private static native boolean initIDs();
    // These functions need to be synchronized as
    // CUPS does not support multi-threading.
    private static synchronized native String[] getMedia(String printer);
    private static synchronized native float[] getPageSizes(String printer);
    private static synchronized native String[] getOutputBins(String printer);
    private static synchronized native void
        getResolutions(String printer, ArrayList<Integer> resolutionList);
    //public static boolean useIPPMedia = false; will be used later

    private MediaPrintableArea[] cupsMediaPrintables;
    private MediaSizeName[] cupsMediaSNames;
    private CustomMediaSizeName[] cupsCustomMediaSNames;
    private MediaTray[] cupsMediaTrays;
    private OutputBin[] cupsOutputBins;

    public  int nPageSizes = 0;
    public  int nTrays = 0;
    private  String[] media;
    private  String[] outputBins;
    private  float[] pageSizes;
    int[]   resolutionsArray;
    private String printer;

    private static boolean libFound;
    private static String cupsServer = null;
    private static String domainSocketPathname = null;
    private static int cupsPort = 0;

    static {
        initStatic();
    }

    @SuppressWarnings("restricted")
    private static void initStatic() {
        // load awt library to access native code
        System.loadLibrary("awt");
        libFound = initIDs();
        if (libFound) {
           cupsServer = getCupsServer();
           // Is this a local domain socket pathname?
           if (cupsServer != null && cupsServer.startsWith("/")) {
               if (isSandboxedApp()) {
                   domainSocketPathname = cupsServer;
               }
               cupsServer = "localhost";
           }
           cupsPort = getCupsPort();
        }
    }


    CUPSPrinter (String printerName) {
        if (printerName == null) {
            throw new IllegalArgumentException("null printer name");
        }
        printer = printerName;
        cupsMediaSNames = null;
        cupsMediaPrintables = null;
        cupsMediaTrays = null;
        initialized = false;

        if (!libFound) {
            throw new RuntimeException("cups lib not found");
        } else {
            // get page + tray names
            media =  getMedia(printer);
            if (media == null) {
                // either PPD file is not found or printer is unknown
                throw new RuntimeException("error getting PPD");
            }

            // get sizes
            pageSizes = getPageSizes(printer);
            if (pageSizes != null) {
                nPageSizes = pageSizes.length/6;

                nTrays = media.length/2-nPageSizes;
                assert (nTrays >= 0);
            }
            ArrayList<Integer> resolutionList = new ArrayList<>();
            getResolutions(printer, resolutionList);
            resolutionsArray = new int[resolutionList.size()];
            for (int i=0; i < resolutionList.size(); i++) {
                resolutionsArray[i] = resolutionList.get(i);
            }

            outputBins = getOutputBins(printer);
        }
    }


    /**
     * Returns array of MediaSizeNames derived from PPD.
     */
    MediaSizeName[] getMediaSizeNames() {
        initMedia();
        return cupsMediaSNames;
    }


    /**
     * Returns array of Custom MediaSizeNames derived from PPD.
     */
    CustomMediaSizeName[] getCustomMediaSizeNames() {
        initMedia();
        return cupsCustomMediaSNames;
    }

    public int getDefaultMediaIndex() {
        return ((pageSizes.length >1) ? (int)(pageSizes[pageSizes.length -1]) : 0);
    }

    /**
     * Returns array of MediaPrintableArea derived from PPD.
     */
    MediaPrintableArea[] getMediaPrintableArea() {
        initMedia();
        return cupsMediaPrintables;
    }

    /**
     * Returns array of MediaTrays derived from PPD.
     */
    MediaTray[] getMediaTrays() {
        initMedia();
        return cupsMediaTrays;
    }

    /**
     * Returns array of OutputBins derived from PPD.
     */
    OutputBin[] getOutputBins() {
        initMedia();
        return cupsOutputBins;
    }

    /**
     * return the raw packed array of supported printer resolutions.
     */
    int[] getRawResolutions() {
        return resolutionsArray;
    }

    /**
     * Initialize media by translating PPD info to PrintService attributes.
     */
    private synchronized void initMedia() {
        if (initialized) {
            return;
        } else {
            initialized = true;
        }

        if (pageSizes == null) {
            return;
        }

        cupsMediaPrintables = new MediaPrintableArea[nPageSizes];
        cupsMediaSNames = new MediaSizeName[nPageSizes];
        cupsCustomMediaSNames = new CustomMediaSizeName[nPageSizes];

        CustomMediaSizeName msn;
        MediaPrintableArea mpa;
        float length, width, x, y, w, h;

        // initialize names and printables
        for (int i=0; i<nPageSizes; i++) {
            // media width and length
            width = (float)(pageSizes[i*6]/PRINTER_DPI);
            length = (float)(pageSizes[i*6+1]/PRINTER_DPI);
            // media printable area
            x = (float)(pageSizes[i*6+2]/PRINTER_DPI);
            h = (float)(pageSizes[i*6+3]/PRINTER_DPI);
            w = (float)(pageSizes[i*6+4]/PRINTER_DPI);
            y = (float)(pageSizes[i*6+5]/PRINTER_DPI);

            msn = CustomMediaSizeName.create(media[i*2], media[i*2+1],
                                             width, length);

            // add to list of standard MediaSizeNames
            if ((cupsMediaSNames[i] = msn.getStandardMedia()) == null) {
                // add custom if no matching standard media
                cupsMediaSNames[i] = msn;
            }

            // add to list of custom MediaSizeName
            // for internal use of IPPPrintService
            cupsCustomMediaSNames[i] = msn;

            mpa = null;
            try {
                mpa = new MediaPrintableArea(x, y, w, h,
                                             MediaPrintableArea.INCH);
            } catch (IllegalArgumentException e) {
                if (width > 0 && length > 0) {
                    mpa = new MediaPrintableArea(0, 0, width, length,
                                             MediaPrintableArea.INCH);
                }
            }
            cupsMediaPrintables[i] = mpa;
        }

        // initialize trays
        cupsMediaTrays = new MediaTray[nTrays];

        MediaTray mt;
        for (int i=0; i<nTrays; i++) {
            mt = CustomMediaTray.create(media[(nPageSizes+i)*2],
                                        media[(nPageSizes+i)*2+1]);
            cupsMediaTrays[i] = mt;
        }

        if (outputBins == null) {
            cupsOutputBins = new OutputBin[0];
        } else {
            int nBins = outputBins.length / 2;
            cupsOutputBins = new OutputBin[nBins];
            for (int i = 0; i < nBins; i++) {
                cupsOutputBins[i] = CustomOutputBin.createOutputBin(outputBins[i*2], outputBins[i*2+1]);
            }
        }
    }

    /**
     * Get CUPS default printer using IPP.
     * Returns 2 values - index 0 is printer name, index 1 is the uri.
     */
    static String[] getDefaultPrinter() {
        // Try to get user/lpoptions-defined printer name from CUPS
        // if not user-set, then go for server default destination
        String[] printerInfo = new String[2];
        printerInfo[0] = getCupsDefaultPrinter();

        if (printerInfo[0] != null) {
            printerInfo[1] = null;
            return printerInfo.clone();
        }
        try {
            @SuppressWarnings("deprecation")
            URL url = new URL("http", getServer(), getPort(), "");
            final HttpURLConnection urlConnection =
                IPPPrintService.getIPPConnection(url);

            if (urlConnection != null) {
                OutputStream os = null;
                try {
                    os = urlConnection.getOutputStream();
                } catch (Exception e) {
                   IPPPrintService.debug_println(debugPrefix+e);
                }

                if (os == null) {
                    return null;
                }

                AttributeClass[] attCl = {
                    AttributeClass.ATTRIBUTES_CHARSET,
                    AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
                    new AttributeClass("requested-attributes",
                                       AttributeClass.TAG_URI,
                                       "printer-uri")
                };

                if (IPPPrintService.writeIPPRequest(os,
                                        IPPPrintService.OP_CUPS_GET_DEFAULT,
                                        attCl)) {

                    HashMap<String, AttributeClass> defaultMap = null;

                    InputStream is = urlConnection.getInputStream();
                    HashMap<String, AttributeClass>[] responseMap = IPPPrintService.readIPPResponse(
                                         is);
                    is.close();

                    if (responseMap != null && responseMap.length > 0) {
                        defaultMap = responseMap[0];
                    } else {
                       IPPPrintService.debug_println(debugPrefix+
                           " empty response map for GET_DEFAULT.");
                    }

                    if (defaultMap == null) {
                        os.close();
                        urlConnection.disconnect();

                        /* CUPS on OS X, as initially configured, considers the
                         * default printer to be the last one used that's
                         * presently available. So if no default was
                         * reported, exec lpstat -d which has all the Apple
                         * special behaviour for this built in.
                         */
                         if (PrintServiceLookupProvider.isMac()) {
                             printerInfo[0] = PrintServiceLookupProvider.
                                                   getDefaultPrinterNameSysV();
                             printerInfo[1] = null;
                             return printerInfo.clone();
                         } else {
                             return null;
                         }
                    }


                    AttributeClass attribClass = defaultMap.get("printer-name");

                    if (attribClass != null) {
                        printerInfo[0] = attribClass.getStringValue();
                        attribClass = defaultMap.get("printer-uri-supported");
                        IPPPrintService.debug_println(debugPrefix+
                          "printer-uri-supported="+attribClass);
                        if (attribClass != null) {
                            printerInfo[1] = attribClass.getStringValue();
                        } else {
                            printerInfo[1] = null;
                        }
                        os.close();
                        urlConnection.disconnect();
                        return printerInfo.clone();
                    }
                }
                os.close();
                urlConnection.disconnect();
            }
        } catch (Exception e) {
        }
        return null;
    }


    /**
     * Get list of all CUPS printers using IPP.
     */
    static String[] getAllPrinters() {

        if (getDomainSocketPathname() != null) {
            String[] printerNames = getCupsDefaultPrinters();
            if (printerNames != null && printerNames.length > 0) {
                String[] printerURIs = new String[printerNames.length];
                for (int i=0; i< printerNames.length; i++) {
                    printerURIs[i] = String.format("ipp://%s:%d/printers/%s",
                            getServer(), getPort(), printerNames[i]);
                }
                return printerURIs;
            }
            return null;
        }

        try {
            @SuppressWarnings("deprecation")
            URL url = new URL("http", getServer(), getPort(), "");

            final HttpURLConnection urlConnection =
                IPPPrintService.getIPPConnection(url);

            if (urlConnection != null) {
                OutputStream os = null;
                try {
                    os = urlConnection.getOutputStream();
                } catch (Exception e) {
                }

                if (os == null) {
                    return null;
                }

                AttributeClass[] attCl = {
                    AttributeClass.ATTRIBUTES_CHARSET,
                    AttributeClass.ATTRIBUTES_NATURAL_LANGUAGE,
                    new AttributeClass("requested-attributes",
                                       AttributeClass.TAG_KEYWORD,
                                       "printer-uri-supported")
                };

                if (IPPPrintService.writeIPPRequest(os,
                                IPPPrintService.OP_CUPS_GET_PRINTERS, attCl)) {

                    InputStream is = urlConnection.getInputStream();
                    HashMap<String, AttributeClass>[] responseMap =
                        IPPPrintService.readIPPResponse(is);

                    is.close();
                    os.close();
                    urlConnection.disconnect();

                    if (responseMap == null || responseMap.length == 0) {
                        return null;
                    }

                    ArrayList<String> printerNames = new ArrayList<>();
                    for (int i=0; i< responseMap.length; i++) {
                        AttributeClass attribClass =
                            responseMap[i].get("printer-uri-supported");

                        if (attribClass != null) {
                            String nameStr = attribClass.getStringValue();
                            printerNames.add(nameStr);
                        }
                    }
                    return printerNames.toArray(new String[] {});
                } else {
                    os.close();
                    urlConnection.disconnect();
                }
            }

        } catch (Exception e) {
        }
        return null;

    }

    /**
     * Returns CUPS server name.
     */
    public static String getServer() {
        return cupsServer;
    }

    /**
     * Returns CUPS port number.
     */
    public static int getPort() {
        return cupsPort;
    }

    /**
     * Returns CUPS domain socket pathname.
     */
    private static String getDomainSocketPathname() {
        return domainSocketPathname;
    }

    private static boolean isSandboxedApp() {
        if (PrintServiceLookupProvider.isMac()) {
            return (System.getenv("APP_SANDBOX_CONTAINER_ID") != null);
        }
        return false;
    }


    /**
     * Detects if CUPS is running.
     */
    public static boolean isCupsRunning() {
        IPPPrintService.debug_println(debugPrefix+"libFound "+libFound);
        if (libFound) {
            String server = getDomainSocketPathname() != null
                    ? getDomainSocketPathname()
                    : getServer();
            IPPPrintService.debug_println(debugPrefix+"CUPS server "+server+
                                          " port "+getPort()+
                                          (getDomainSocketPathname() != null
                                                  ? " use domain socket pathname"
                                                  : ""));
            return canConnect(server, getPort());
        } else {
            return false;
        }
    }


}
