import com.denova.runtime.Exec;
import com.denova.runtime.OS;
import com.denova.runtime.WindowsConstants;
import com.denova.runtime.WindowsDirs;
import com.denova.ui.Swinger;
import com.denova.util.PropertyList;
import com.denova.JExpress.Installer.CustomInstaller;
import com.denova.JExpress.Installer.CustomUninstaller;
import com.denova.JExpress.Installer.InstallPropertyNames;
import com.denova.JExpress.Installer.StatusPanel;
import java.io.File;
import java.util.Iterator;


/**
    Configure all menus flagged as "start after login" to install as a service.

    Note: 
     1. This class is no longer needed as you can simply use the Advanced interface
        for JExpress and check which launchers that you want installed as a service.
     2. You should include this class "After uninstaller created" on the Custom panel.
     3. You're welcome to adapt this class to use with a JExpress Installer or Updater.
     
    Copyright (C) 1998-2012 DeNova
    Last modified: 2012-06-15
*/
public class InstallService extends StatusPanel
                            implements InstallPropertyNames
{
    private String progressLabel = CustomInstaller.getLocalizedString("Configuring") + " services";
    

    private class ServiceSwinger extends Swinger
    {
        public void swingBefore()
        {
            updateProgressBarLabel(progressLabel);
        }
        
        public void workInBackground()
        {
            String installDir = getPropertyList().getProperty(ApplicationDirectory, "");
            PropertyList menus = getPropertyList().getPropertyListProperty(
                MenusAttributeName);
            Iterator menusEnum = menus.propertyNamesList().iterator();
            while (menusEnum.hasNext())
            {
                String menuName = (String)menusEnum.next();
                String propsString = menus.getProperty(menuName);
    
                if (propsString != null)
                {
                    PropertyList props = new PropertyList();
                    props.fromString(propsString);

                    String longName = props.getProperty(MenuLongName, "").trim();
                    String shortName = props.getProperty(MenuShortName, "").trim();
                    boolean addStartupMenu = props.getBooleanProperty(MenuAutoStartup, false);
                    if (okToAddService(longName, shortName) && addStartupMenu)
                    {
                        String serviceName = getServiceName(longName, shortName);
                        CustomInstaller.logToInstaller("adding service for " + serviceName);
                        String executable = getExecutable(
                            serviceName, shortName, props, installDir);
                        
                        if (addService(serviceName, executable, installDir))
                        {
                            removeAutoStartup(serviceName, props);
                        }
                    }
                }
            }
        }
        
        public void swingAfter()
        {
            // since there's no user interaction, simply move to the next panel
            showNextPanel();
        }
        
        private boolean okToAddService(String longName,
                                       String shortName)
        {
            boolean ok = false;
            
            if (OS.isWindows())
            {
                ok = longName.length() > 0;
            }
            
            else
            {
                ok = shortName.length() > 0;
            }
            
            return ok;
        }
        
        
        private String getServiceName(String longName,
                                      String shortName)
        {
            String serviceName = longName;
            
            if (serviceName.length() <= 0)
            {
                serviceName = shortName;
            }
            
            return serviceName;
        }
        
        
        private String getExecutable(String longName,
                                     String shortName,
                                     PropertyList props,
                                     String installDir)
        {
            File executable;
            String exec = props.getProperty(MenuExecutableFile);
            boolean javaCommand = props.getBooleanProperty(MenuUseJavaCommandPrefix);
            
            if (javaCommand)
            {
                if (OS.isWindows())
                {
                     executable = new File(installDir, longName + ".exe");
                }
                else
                {
                    executable = new File(installDir, shortName);
                }
            }
            
            else
            {
                 executable = new File(installDir, exec);                
            }
            
            return executable.getPath();
        }
        
        
        private boolean addService(String serviceName, 
                                   String executable,
                                   String installDir)
        {
            boolean ok = OS.installService(serviceName, executable);
            
            CustomInstaller.logToInstaller("successful: " + ok);
            
            if (ok)
            {
                CustomUninstaller customUninstaller = new CustomUninstaller();
                
                if (OS.isWindows())
                {
                    customUninstaller.removeWindowsService(serviceName, executable);
                }
                else if (OS.isLinux())
                {
                    customUninstaller.removeLinuxService(executable);
                }
                customUninstaller.append(installDir);
            }
            
            return ok;
        }
        
        
        private void removeAutoStartup(String serviceName, 
                                       PropertyList menuProperties)
        {
            if (OS.isWindows())
            {
                boolean allUsers = menuProperties.getBooleanProperty(MenuAllUsers);
                String user = WindowsConstants.CurrentUser;
                if (allUsers)
                {
                    user = WindowsConstants.AllUsers;
                }
                
                String startupDir = WindowsDirs.getStartupMenuDir(user);
                File f = new File(startupDir, "Autostart " + serviceName + ".lnk");
                f.delete();
            }
        }
    }
    
    
    /**
     * Creates a new InstallService object.
     * 
     * @param properties installer's properties
     */
    public InstallService(PropertyList properties)
    {
        super (properties);
        
        updateProgressBarLabel(progressLabel);
        CustomInstaller.log("instantiated install service");
    }

    /** 
     * Enter the panel. Method where the work for the class is done.
     *
     * Do not call this method; only the wizard should call it.
     */
    public synchronized void enter()
    {
        CustomInstaller.log("entering install service");
        if (OS.supportServices())
        {
            ServiceSwinger swinger = new ServiceSwinger();
            swinger.execute();
        }
        
        else
        {
            showNextPanel();
        }
    }

}