/*
 * Copyright (c) 2000, 2008, 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.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Vector;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import javax.print.DocFlavor;
import javax.print.MultiDocPrintService;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.PrintRequestAttribute;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import java.io.File;
import java.io.FileReader;
import java.net.URL;

/*
 * Remind: This class uses solaris commands. We also need a linux
 * version
 */
public class UnixPrintServiceLookup extends PrintServiceLookup
    implements BackgroundServiceLookup, Runnable {

    /* Remind: the current implementation is static, as its assumed
     * its preferable to minimise creation of PrintService instances.
     * Later we should add logic to add/remove services on the fly which
     * will take a hit of needing to regather the list of services.
     */
    private String defaultPrinter;
    private PrintService defaultPrintService;
    private PrintService[] printServices; /* includes the default printer */
    private Vector lookupListeners = null;
    private static String debugPrefix = "UnixPrintServiceLookup>> ";
    private static boolean pollServices = true;
    private static final int DEFAULT_MINREFRESH = 120;  // 2 minutes
    private static int minRefreshTime = DEFAULT_MINREFRESH;


    static String osname;

    static {
        /* The system property "sun.java2d.print.polling"
         * can be used to force the printing code to poll or not poll
         * for PrintServices.
         */
        String pollStr = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("sun.java2d.print.polling"));

        if (pollStr != null) {
            if (pollStr.equalsIgnoreCase("true")) {
                pollServices = true;
            } else if (pollStr.equalsIgnoreCase("false")) {
                pollServices = false;
            }
        }

        /* The system property "sun.java2d.print.minRefreshTime"
         * can be used to specify minimum refresh time (in seconds)
         * for polling PrintServices.  The default is 120.
         */
        String refreshTimeStr = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction(
                "sun.java2d.print.minRefreshTime"));

        if (refreshTimeStr != null) {
            try {
                minRefreshTime = (new Integer(refreshTimeStr)).intValue();
            } catch (NumberFormatException e) {
            }
            if (minRefreshTime < DEFAULT_MINREFRESH) {
                minRefreshTime = DEFAULT_MINREFRESH;
            }
        }

        osname = java.security.AccessController.doPrivileged(
            new sun.security.action.GetPropertyAction("os.name"));
    }

    static boolean isSysV() {
        return osname.equals("SunOS");
    }

    static boolean isBSD() {
        return osname.equals("Linux");
    }

    static final int UNINITIALIZED = -1;
    static final int BSD_LPD = 0;
    static final int BSD_LPD_NG = 1;

    static int cmdIndex = UNINITIALIZED;

    String[] lpcFirstCom = {
        "/usr/sbin/lpc status | grep : | sed -ne '1,1 s/://p'",
        "/usr/sbin/lpc status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
    };

    String[] lpcAllCom = {
        "/usr/sbin/lpc status | grep : | sed -e 's/://'",
        "/usr/sbin/lpc -a status | grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}' | sort"
    };

    String[] lpcNameCom = {
        "| grep : | sed -ne 's/://p'",
        "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk -F'@' '{print $1}'"
    };


    static int getBSDCommandIndex() {
        String command  = "/usr/sbin/lpc status";
        String[] names = execCmd(command);

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

        for (int i=0; i<names.length; i++) {
            if (names[i].indexOf('@') != -1) {
                return BSD_LPD_NG;
            }
        }

        return BSD_LPD;
    }


    public UnixPrintServiceLookup() {
        // start the printer listener thread
        if (pollServices) {
            PrinterChangeListener thr = new PrinterChangeListener();
            thr.setDaemon(true);
            thr.start();
            IPPPrintService.debug_println(debugPrefix+"polling turned on");
        }
    }

    /* Want the PrintService which is default print service to have
     * equality of reference with the equivalent in list of print services
     * This isn't required by the API and there's a risk doing this will
     * lead people to assume its guaranteed.
     */
    public synchronized PrintService[] getPrintServices() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPrintJobAccess();
        }

        if (printServices == null || !pollServices) {
            refreshServices();
        }
        if (printServices == null) {
            return new PrintService[0];
        } else {
            return printServices;
        }
    }


    // refreshes "printServices"
    public synchronized void refreshServices() {
        /* excludes the default printer */
        String[] printers = null; // array of printer names
        String[] printerURIs = null; //array of printer URIs

        getDefaultPrintService();
        if (CUPSPrinter.isCupsRunning()) {
            printerURIs = CUPSPrinter.getAllPrinters();
            if ((printerURIs != null) && (printerURIs.length > 0)) {
                printers = new String[printerURIs.length];
                for (int i=0; i<printerURIs.length; i++) {
                    int lastIndex = printerURIs[i].lastIndexOf("/");
                    printers[i] = printerURIs[i].substring(lastIndex+1);
                }
            }
        } else {
            if (isSysV()) {
                printers = getAllPrinterNamesSysV();
            } else { //BSD
                printers = getAllPrinterNamesBSD();
            }
        }

        if (printers == null) {
            if (defaultPrintService != null) {
                printServices = new PrintService[1];
                printServices[0] = defaultPrintService;
            } else {
                printServices = null;
            }
            return;
        }

        ArrayList printerList = new ArrayList();
        int defaultIndex = -1;
        for (int p=0; p<printers.length; p++) {
            if (printers[p] == null) {
                continue;
            }
            if ((defaultPrintService != null)
                && printers[p].equals(defaultPrintService.getName())) {
                printerList.add(defaultPrintService);
                defaultIndex = printerList.size() - 1;
            } else {
                if (printServices == null) {
                    IPPPrintService.debug_println(debugPrefix+
                                                  "total# of printers = "+printers.length);

                    if (CUPSPrinter.isCupsRunning()) {
                        try {
                            printerList.add(new IPPPrintService(printers[p],
                                                                printerURIs[p],
                                                                true));
                        } catch (Exception e) {
                            IPPPrintService.debug_println(debugPrefix+
                                                          " getAllPrinters Exception "+
                                                          e);

                        }
                    } else {
                        printerList.add(new UnixPrintService(printers[p]));
                    }
                } else {
                    int j;
                    for (j=0; j<printServices.length; j++) {
                        if ((printServices[j] != null) &&
                            (printers[p].equals(printServices[j].getName()))) {
                            printerList.add(printServices[j]);
                            printServices[j] = null;
                            break;
                        }
                    }

                    if (j == printServices.length) {      // not found?
                        if (CUPSPrinter.isCupsRunning()) {
                            try {
                                printerList.add(new IPPPrintService(
                                                               printers[p],
                                                               printerURIs[p],
                                                               true));
                            } catch (Exception e) {
                                IPPPrintService.debug_println(debugPrefix+
                                                              " getAllPrinters Exception "+
                                                              e);

                            }
                        } else {
                            printerList.add(new UnixPrintService(printers[p]));
                        }
                    }
                }
            }
        }

        // Look for deleted services and invalidate these
        if (printServices != null) {
            for (int j=0; j < printServices.length; j++) {
                if ((printServices[j] instanceof UnixPrintService) &&
                    (!printServices[j].equals(defaultPrintService))) {
                    ((UnixPrintService)printServices[j]).invalidateService();
                }
            }
        }

        //if defaultService is not found in printerList
        if (defaultIndex == -1 && defaultPrintService != null) {
            //add default to the list
            printerList.add(defaultPrintService);
            defaultIndex = printerList.size() - 1;
        }

        printServices = (PrintService[])printerList.toArray(
                                      new PrintService[] {});

        // swap default with the first in the list
        if (defaultIndex > 0) {
            PrintService saveService = printServices[0];
            printServices[0] = printServices[defaultIndex];
            printServices[defaultIndex] = saveService;
        }
    }

    private boolean matchesAttributes(PrintService service,
                                      PrintServiceAttributeSet attributes) {

        Attribute [] attrs =  attributes.toArray();
        Attribute serviceAttr;
        for (int i=0; i<attrs.length; i++) {
            serviceAttr
                = service.getAttribute((Class<PrintServiceAttribute>)attrs[i].getCategory());
            if (serviceAttr == null || !serviceAttr.equals(attrs[i])) {
                return false;
            }
        }
        return true;
    }

      /* This checks for validity of the printer name before passing as
       * parameter to a shell command.
       */
      private boolean checkPrinterName(String s) {
        char c;

        for (int i=0; i < s.length(); i++) {
          c = s.charAt(i);
          if (Character.isLetterOrDigit(c) ||
              c == '-' || c == '_' || c == '.' || c == '/') {
            continue;
          } else {
            return false;
          }
        }
        return true;
      }

    /* On a network with many (hundreds) of network printers, it
     * can save several seconds if you know all you want is a particular
     * printer, to ask for that printer rather than retrieving all printers.
     */
    private PrintService getServiceByName(PrinterName nameAttr) {
        String name = nameAttr.getValue();
        PrintService printer = null;
        if (name == null || name.equals("") || !checkPrinterName(name)) {
            return null;
        }
        if (isSysV()) {
            printer = getNamedPrinterNameSysV(name);
        } else {
            printer = getNamedPrinterNameBSD(name);
        }
        return printer;
    }

    private PrintService[]
        getPrintServices(PrintServiceAttributeSet serviceSet) {

        if (serviceSet == null || serviceSet.isEmpty()) {
            return getPrintServices();
        }

        /* Typically expect that if a service attribute is specified that
         * its a printer name and there ought to be only one match.
         * Directly retrieve that service and confirm
         * that it meets the other requirements.
         * If printer name isn't mentioned then go a slow path checking
         * all printers if they meet the reqiremements.
         */
        PrintService[] services;
        PrinterName name = (PrinterName)serviceSet.get(PrinterName.class);
        PrintService defService;
        if (name != null && (defService = getDefaultPrintService()) != null) {
            /* To avoid execing a unix command  see if the client is asking
             * for the default printer by name, since we already have that
             * initialised.
             */

            PrinterName defName =
                (PrinterName)defService.getAttribute(PrinterName.class);

            if (defName != null && name.equals(defName)) {
                if (matchesAttributes(defService, serviceSet)) {
                    services = new PrintService[1];
                    services[0] = defService;
                    return services;
                } else {
                    return new PrintService[0];
                }
            } else {
                /* Its not the default service */
                PrintService service = getServiceByName(name);
                if (service != null &&
                    matchesAttributes(service, serviceSet)) {
                    services = new PrintService[1];
                    services[0] = service;
                    return services;
                } else {
                    return new PrintService[0];
                }
            }
        } else {
            /* specified service attributes don't include a name.*/
            Vector matchedServices = new Vector();
            services = getPrintServices();
            for (int i = 0; i< services.length; i++) {
                if (matchesAttributes(services[i], serviceSet)) {
                    matchedServices.add(services[i]);
                }
            }
            services = new PrintService[matchedServices.size()];
            for (int i = 0; i< services.length; i++) {
                services[i] = (PrintService)matchedServices.elementAt(i);
            }
            return services;
        }
    }

    /*
     * If service attributes are specified then there must be additional
     * filtering.
     */
    public PrintService[] getPrintServices(DocFlavor flavor,
                                           AttributeSet attributes) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }
        PrintRequestAttributeSet requestSet = null;
        PrintServiceAttributeSet serviceSet = null;

        if (attributes != null && !attributes.isEmpty()) {

            requestSet = new HashPrintRequestAttributeSet();
            serviceSet = new HashPrintServiceAttributeSet();

            Attribute[] attrs = attributes.toArray();
            for (int i=0; i<attrs.length; i++) {
                if (attrs[i] instanceof PrintRequestAttribute) {
                    requestSet.add(attrs[i]);
                } else if (attrs[i] instanceof PrintServiceAttribute) {
                    serviceSet.add(attrs[i]);
                }
            }
        }

        PrintService[] services = getPrintServices(serviceSet);
        if (services.length == 0) {
            return services;
        }

        if (CUPSPrinter.isCupsRunning()) {
            ArrayList matchingServices = new ArrayList();
            for (int i=0; i<services.length; i++) {
                try {
                    if (services[i].
                        getUnsupportedAttributes(flavor, requestSet) == null) {
                        matchingServices.add(services[i]);
                    }
                } catch (IllegalArgumentException e) {
                }
            }
            services = new PrintService[matchingServices.size()];
            return (PrintService[])matchingServices.toArray(services);

        } else {
            // We only need to compare 1 PrintService because all
            // UnixPrintServices are the same anyway.  We will not use
            // default PrintService because it might be null.
            PrintService service = services[0];
            if ((flavor == null ||
                 service.isDocFlavorSupported(flavor)) &&
                 service.getUnsupportedAttributes(flavor, requestSet) == null)
            {
                return services;
            } else {
                return new PrintService[0];
            }
        }
    }

    /*
     * return empty array as don't support multi docs
     */
    public MultiDocPrintService[]
        getMultiDocPrintServices(DocFlavor[] flavors,
                                 AttributeSet attributes) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }
        return new MultiDocPrintService[0];
    }


    public synchronized PrintService getDefaultPrintService() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
          security.checkPrintJobAccess();
        }

        // clear defaultPrintService
        defaultPrintService = null;

        IPPPrintService.debug_println("isRunning ? "+
                                      (CUPSPrinter.isCupsRunning()));
        if (CUPSPrinter.isCupsRunning()) {
            defaultPrinter = CUPSPrinter.getDefaultPrinter();
        } else {
            if (isSysV()) {
                defaultPrinter = getDefaultPrinterNameSysV();
            } else {
                defaultPrinter = getDefaultPrinterNameBSD();
            }
        }
        if (defaultPrinter == null) {
            return null;
        }
        defaultPrintService = null;
        if (printServices != null) {
            for (int j=0; j<printServices.length; j++) {
                if (defaultPrinter.equals(printServices[j].getName())) {
                    defaultPrintService = printServices[j];
                    break;
                }
            }
        }
        if (defaultPrintService == null) {
            if (CUPSPrinter.isCupsRunning()) {
                try {
                    PrintService defaultPS =
                        new IPPPrintService(defaultPrinter,
                                            new URL("http://"+
                                                    CUPSPrinter.getServer()+":"+
                                                    CUPSPrinter.getPort()+"/"+
                                                    defaultPrinter));
                    defaultPrintService = defaultPS;
                } catch (Exception e) {
                }
            } else {
                defaultPrintService = new UnixPrintService(defaultPrinter);
            }
        }

        return defaultPrintService;
    }

    public synchronized void
        getServicesInbackground(BackgroundLookupListener listener) {
        if (printServices != null) {
            listener.notifyServices(printServices);
        } else {
            if (lookupListeners == null) {
                lookupListeners = new Vector();
                lookupListeners.add(listener);
                Thread lookupThread = new Thread(this);
                lookupThread.start();
            } else {
                lookupListeners.add(listener);
            }
        }
    }

    /* This method isn't used in most cases because we rely on code in
     * javax.print.PrintServiceLookup. This is needed just for the cases
     * where those interfaces are by-passed.
     */
    private PrintService[] copyOf(PrintService[] inArr) {
        if (inArr == null || inArr.length == 0) {
            return inArr;
        } else {
            PrintService []outArr = new PrintService[inArr.length];
            System.arraycopy(inArr, 0, outArr, 0, inArr.length);
            return outArr;
        }
    }

    public void run() {
        PrintService[] services = getPrintServices();
        synchronized (this) {
            BackgroundLookupListener listener;
            for (int i=0; i<lookupListeners.size(); i++) {
                listener =
                    (BackgroundLookupListener)lookupListeners.elementAt(i);
                listener.notifyServices(copyOf(services));
            }
            lookupListeners = null;
        }
    }

    private String getDefaultPrinterNameBSD() {
        if (cmdIndex == UNINITIALIZED) {
            cmdIndex = getBSDCommandIndex();
        }
        String[] names = execCmd(lpcFirstCom[cmdIndex]);
        if (names == null || names.length == 0) {
            return null;
        }

        if ((cmdIndex==BSD_LPD_NG) &&
            (names[0].startsWith("missingprinter"))) {
            return null;
        }
        return names[0];
    }

    private PrintService getNamedPrinterNameBSD(String name) {
      if (cmdIndex == UNINITIALIZED) {
        cmdIndex = getBSDCommandIndex();
      }
      String command = "/usr/sbin/lpc status " + name + lpcNameCom[cmdIndex];
      String[] result = execCmd(command);

      if (result == null || !(result[0].equals(name))) {
          return null;
      }
      return new UnixPrintService(name);
    }

    private String[] getAllPrinterNamesBSD() {
        if (cmdIndex == UNINITIALIZED) {
            cmdIndex = getBSDCommandIndex();
        }
        String[] names = execCmd(lpcAllCom[cmdIndex]);
        if (names == null || names.length == 0) {
          return null;
        }
        return names;
    }

    private String getDefaultPrinterNameSysV() {
        String defaultPrinter = "lp";
        String command = "/usr/bin/lpstat -d";

        String [] names = execCmd(command);
        if (names == null || names.length == 0) {
            return defaultPrinter;
        } else {
            int index = names[0].indexOf(":");
            if (index == -1  || (names[0].length() <= index+1)) {
                return null;
            } else {
                String name = names[0].substring(index+1).trim();
                if (name.length() == 0) {
                    return null;
                } else {
                    return name;
                }
            }
        }
    }

    private PrintService getNamedPrinterNameSysV(String name) {

        String command = "/usr/bin/lpstat -v " + name;
        String []result = execCmd(command);

        if (result == null || result[0].indexOf("unknown printer") > 0) {
            return null;
        } else {
            return new UnixPrintService(name);
        }
    }

    private String[] getAllPrinterNamesSysV() {
        String defaultPrinter = "lp";
        String command = "/usr/bin/lpstat -v|/usr/bin/expand|/usr/bin/cut -f3 -d' ' |/usr/bin/cut -f1 -d':' | /usr/bin/sort";

        String [] names = execCmd(command);
        ArrayList printerNames = new ArrayList();
        for (int i=0; i < names.length; i++) {
            if (!names[i].equals("_default") &&
                !names[i].equals(defaultPrinter) &&
                !names[i].equals("")) {
                printerNames.add(names[i]);
            }
        }
        return (String[])printerNames.toArray(new String[printerNames.size()]);
    }

    static String[] execCmd(final String command) {
        ArrayList results = null;
        try {
            final String[] cmd = new String[3];
            if (isSysV()) {
                cmd[0] = "/usr/bin/sh";
                cmd[1] = "-c";
                cmd[2] = "env LC_ALL=C " + command;
            } else {
                cmd[0] = "/bin/sh";
                cmd[1] = "-c";
                cmd[2] = "LC_ALL=C " + command;
            }

            results = (ArrayList)AccessController.doPrivileged(
                new PrivilegedExceptionAction() {
                    public Object run() throws IOException {

                        Process proc;
                        BufferedReader bufferedReader = null;
                        File f = File.createTempFile("prn","xc");
                        cmd[2] = cmd[2]+">"+f.getAbsolutePath();

                        proc = Runtime.getRuntime().exec(cmd);
                        try {
                            boolean done = false; // in case of interrupt.
                            while (!done) {
                                try {
                                    proc.waitFor();
                                    done = true;
                                } catch (InterruptedException e) {
                                }
                            }

                            if (proc.exitValue() == 0) {
                                FileReader reader = new FileReader(f);
                                bufferedReader = new BufferedReader(reader);
                                String line;
                                ArrayList results = new ArrayList();
                                while ((line = bufferedReader.readLine())
                                       != null) {
                                    results.add(line);
                                }
                                return results;
                            }
                        } finally {
                            f.delete();
                            // promptly close all streams.
                            if (bufferedReader != null) {
                                bufferedReader.close();
                            }
                            proc.getInputStream().close();
                            proc.getErrorStream().close();
                            proc.getOutputStream().close();
                        }
                        return null;
                    }
                });
        } catch (PrivilegedActionException e) {
        }
        if (results == null) {
            return new String[0];
        } else {
            return (String[])results.toArray(new String[results.size()]);
        }
    }

    private class PrinterChangeListener extends Thread {

        public void run() {
            int refreshSecs;
            while (true) {
                try {
                    refreshServices();
                } catch (Exception se) {
                    IPPPrintService.debug_println(debugPrefix+"Exception in refresh thread.");
                    break;
                }

                if ((printServices != null) &&
                    (printServices.length > minRefreshTime)) {
                    // compute new refresh time 1 printer = 1 sec
                    refreshSecs = printServices.length;
                } else {
                    refreshSecs = minRefreshTime;
                }
                try {
                    sleep(refreshSecs * 1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }
}
