/*******************************************************************************
 * Copyright (c) 2010 Shane Clarke.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Shane Clarke - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.ui.wizards;

import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.ClasspathContainerInitializer;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jst.ws.internal.cxf.core.CXFClasspathContainer;
import org.eclipse.jst.ws.internal.cxf.core.CXFCorePlugin;
import org.eclipse.jst.ws.internal.cxf.core.context.CXFPersistentContext;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFFactory;
import org.eclipse.jst.ws.internal.cxf.core.model.CXFInstall;
import org.eclipse.jst.ws.internal.cxf.core.utils.LaunchUtils;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIMessages;
import org.eclipse.jst.ws.internal.cxf.ui.CXFUIPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.common.project.facet.core.IFacetedProject;
import org.eclipse.wst.common.project.facet.core.ProjectFacetsManager;
import org.osgi.framework.Version;

public class CXFInstallWizardPage extends WizardPage {
    private IStatus CXF_LOCATION_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, null);
    private IStatus CXF_TYPE_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, null);
    private IStatus CXF_VERSION_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, null);
    private IStatus OK_STATUS = new Status(IStatus.OK, CXFUIPlugin.PLUGIN_ID, ""); //$NON-NLS-1$

    private Pattern digitPattern = Pattern.compile("\\d"); //$NON-NLS-1$

    private Button browseButton;
    private Text cxfHomeDirText;
    private Text cxfTypeText;
    private Text cxfVersionText;

    String cxfRuntimeVersion = ""; //$NON-NLS-1$
    String cxfRuntimeLocation = ""; //$NON-NLS-1$
    String cxfRuntimeType = ""; //$NON-NLS-1$

    private CXFInstall cxfInstall;

    protected CXFInstallWizardPage() {
        super("cxf.intall.wizard.page"); //$NON-NLS-1$
        setTitle(CXFUIMessages.CXF_INSTALL_WIZARD_PAGE_TITLE);
        setDescription(CXFUIMessages.CXF_INSTALL_WIZARD_PAGE_DESCRIPTION);
        setImageDescriptor(CXFUIPlugin.imageDescriptorFromPlugin(CXFUIPlugin.PLUGIN_ID, "icons/wizban/library_wiz.png"));
    }

    public void createControl(Composite parent) {
        final Composite composite = new Composite(parent, SWT.NONE);

        GridLayout gridLayout = new GridLayout(3, false);
        composite.setLayout(gridLayout);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        composite.setLayoutData(gridData);

        Label label = new Label(composite, SWT.NONE);
        label.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_CXF_HOME_DIR_LABEL);

        cxfHomeDirText = new Text(composite, SWT.BORDER);

        gridData = new GridData(GridData.FILL_HORIZONTAL);
        cxfHomeDirText.setLayoutData(gridData);

        cxfHomeDirText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateLocationStatus();
            }
        });

        browseButton = new Button(composite, SWT.NONE);
        browseButton.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_BROWSE_BUTTON_LABEL);

        browseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                DirectoryDialog fileDialog = new DirectoryDialog(composite.getShell());
                String fileName = fileDialog.open();
                if (fileName != null) {
                    cxfHomeDirText.setText(fileName);
                }
            }
        });

        //CXF Version
        Label cxfVersionLabel = new Label(composite, SWT.NONE);
        cxfVersionLabel.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_CXF_VERSION_LABEL);

        cxfVersionText = new Text(composite, SWT.BORDER | SWT.READ_ONLY);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        cxfVersionText.setLayoutData(gridData);
        cxfVersionText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateVersionStatus();
            }
        });

        //Blank label
        new Label(composite, SWT.NONE);

        //CXF Type
        Label cxfTypeLabel = new Label(composite, SWT.NONE);
        cxfTypeLabel.setText(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_CXF_TYPE_LABEL);

        cxfTypeText = new Text(composite, SWT.BORDER);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        cxfTypeText.setLayoutData(gridData);
        cxfTypeText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                updateTypeStatus();
            }
        });

        if (cxfInstall != null) {
            cxfHomeDirText.setText(cxfInstall.getLocation());
            cxfVersionText.setText(cxfInstall.getVersion());
            cxfTypeText.setText(cxfInstall.getType());
        }

        setControl(composite);
        Dialog.applyDialogFont(composite);
    }

    public void setCXFInstall(CXFInstall cxfInstall) {
        this.cxfInstall = cxfInstall;
    }

    private void updateLocationStatus() {
        CXF_LOCATION_STATUS = checkRuntimeExist(cxfHomeDirText.getText());
        applyStatusToPage(findMostSevere());
    }

    private void updateTypeStatus() {
        CXF_TYPE_STATUS = validateTypeName(cxfTypeText.getText());
        applyStatusToPage(findMostSevere());
    }

    private void updateVersionStatus() {
        CXF_VERSION_STATUS = validateVersion(cxfVersionText.getText());
        applyStatusToPage(findMostSevere());
    }

    private void applyStatusToPage(IStatus status) {
        String message = status.getMessage();
        if (status.getSeverity() > IStatus.OK) {
            setErrorMessage(message);
            setPageComplete(false);

        } else {
            setMessage(getDescription());
            setErrorMessage(null);
            setPageComplete(true);
        }
    }

    private IStatus findMostSevere() {
        if (CXF_TYPE_STATUS.getSeverity() > CXF_LOCATION_STATUS.getSeverity()) {
            return CXF_TYPE_STATUS;
        }
        if (CXF_VERSION_STATUS.getSeverity() > CXF_LOCATION_STATUS.getSeverity()) {
            return CXF_VERSION_STATUS;
        }
        if (CXF_TYPE_STATUS.getSeverity() == CXF_LOCATION_STATUS.getSeverity()) {
            return CXF_LOCATION_STATUS;
        }
        if (CXF_VERSION_STATUS.getSeverity() == CXF_LOCATION_STATUS.getSeverity()) {
            return CXF_LOCATION_STATUS;
        }

        return CXF_LOCATION_STATUS;
    }

    private IStatus checkRuntimeExist(String path) {
        File cxfHomeDir = new File(path);
        if (cxfHomeDirText.getText().trim().equals("")) { //$NON-NLS-1$
            CXF_LOCATION_STATUS = new Status(IStatus.ERROR, CXFUIPlugin.PLUGIN_ID,
                    CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_NOT_SET);
        }
        String cxfLibPath = cxfHomeDir + System.getProperty("file.separator") + "lib"; //$NON-NLS-1$ //$NON-NLS-2$
        if (cxfHomeDir.isDirectory()) {
            File cxfLibFolder = new File(cxfLibPath);
            if (cxfLibFolder.isDirectory()) {
                String[] cxfJarFiles = getCXFJarFiles(cxfLibFolder);
                if (cxfJarFiles != null && cxfJarFiles.length > 0) {
                    IStatus toolVersionStatus = getToolVersion(cxfLibPath);
                    processToolVersion(toolVersionStatus);
                    return CXF_LOCATION_STATUS = OK_STATUS;
                }
            }
        }
        cxfTypeText.setText("");
        cxfVersionText.setText("");
        CXF_LOCATION_STATUS = new Status(Status.ERROR, CXFUIPlugin.PLUGIN_ID,
                CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_RUNTIME_NOT_SET);
        return CXF_LOCATION_STATUS;
    }

    private IStatus validateTypeName(String typeName) {
        if (typeName.trim().length() == 0) {
            CXF_TYPE_STATUS = new Status(Status.ERROR, CXFUIPlugin.PLUGIN_ID, CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_ENTER_TYPE_NAME);
        } else {
            CXF_TYPE_STATUS = OK_STATUS;
        }
        if (!typeName.matches("[a-zA-Z0-9_\\-\\s]+")) {
            CXF_TYPE_STATUS = new Status(Status.ERROR, CXFUIPlugin.PLUGIN_ID,
                    CXFUIMessages.bind(CXFUIMessages.CXF_RUNTIME_PREFERENCE_PAGE_INVALID_TYPE_NAME, typeName));
        } else {
            CXF_TYPE_STATUS = OK_STATUS;
        }
        return CXF_TYPE_STATUS;
    }

    private IStatus validateVersion(String version) {
        if (CXFCorePlugin.getDefault().getJava2WSContext().getInstallations().containsKey(version)
                && cxfInstall != null && !cxfInstall.getVersion().equals(version)) {
            CXF_VERSION_STATUS = new Status(IStatus.ERROR, CXFUIPlugin.PLUGIN_ID, "Version already installed");
        } else {
            CXF_VERSION_STATUS = OK_STATUS;
        }
        return CXF_VERSION_STATUS;
    }

    private String[] getCXFJarFiles(File directory) {
        String[] cxfJarFiles = directory.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.startsWith("cxf") && name.endsWith(".jar") //$NON-NLS-1$ //$NON-NLS-2$
                        && digitPattern.matcher(name).find()) {
                    return true;
                }
                return false;
            }
        });
        return cxfJarFiles;
    }

    private IStatus getToolVersion(String cxLibFolderPath) {
        File cxfLibFolder = new File(cxLibFolderPath);
        List<String> cxfLib = new ArrayList<String>();
        String[] jarFiles = cxfLibFolder.list(new FilenameFilter() {
            public boolean accept(File dir, String name) {
                if (name.endsWith(".jar")) { //$NON-NLS-1$
                    return true;
                }
                return false;
            }
        });

        for (String jarFile : jarFiles) {
            cxfLib.add(cxLibFolderPath + System.getProperty("file.separator") + jarFile); //$NON-NLS-1$
        }

        IStatus toolVersionStatus = LaunchUtils.launch(cxfLib.toArray(new String[cxfLib.size()]),
                "org.apache.cxf.tools.wsdlto.WSDLToJava", new String[] { "-v" }); //$NON-NLS-1$ //$NON-NLS-2$
        return toolVersionStatus;
    }

    private void processToolVersion(IStatus toolVersionStatus) {
        if (toolVersionStatus.getSeverity() == IStatus.INFO) {
            String cxfToolVersion = toolVersionStatus.getMessage();

            cxfToolVersion = cxfToolVersion.substring(cxfToolVersion.indexOf("-") + 1, //$NON-NLS-1$
                    cxfToolVersion.length()).trim();

            Matcher matcher = digitPattern.matcher(cxfToolVersion);
            if (matcher.find()) {
                int start = matcher.start();
                int end = matcher.end();
                while (matcher.find()) {
                    end = matcher.end();
                }
                cxfRuntimeType = cxfToolVersion.substring(0, start).trim();
                cxfRuntimeVersion = cxfToolVersion.substring(start, end);
            }

            Version version = parseVersion(cxfRuntimeVersion);
            cxfRuntimeVersion = version.toString();
            cxfVersionText.setText(cxfRuntimeVersion);
            cxfTypeText.setText(cxfRuntimeType);
            CXFCorePlugin.getDefault().setCurrentRuntimeVersion(version);
        }
    }

    private Version parseVersion(String version) {
    	if (version.trim().length() == 0) {
    		return new Version(0, 0, 0);
    	}
    	String major = null;
    	String minor = null;
    	String micro = null;
        String qualifier = null;
        int segments = 0;
    	for (int index = 0; index < version.length(); index++) {
    	    if (!Character.isDigit(version.charAt(index))) {
    	    	if (version.charAt(index) == '.') { //$NON-NLS-1$
    	    		segments++;
    	    	} else {
    	    		if (major == null) {
    	    			major = "0"; //$NON-NLS-1$
    	    		}
    	    		if (minor == null) {
    	    			minor = "0"; //$NON-NLS-1$
    	    		}
    	    		if (micro == null) {
    	    			micro = "0"; //$NON-NLS-1$
    	    		}
    	    		if (qualifier == null) {
    	    			qualifier = version.substring(index);
    	    		}
    	    	}
    	    } else {
    	    	if (segments == 0) {
    	    		major = findSegment(version, index);
    	    		index += major.length() - 1;
        		} else if (segments == 1) {
    	    		minor = findSegment(version, index);
    	    		index += minor.length() - 1;
        		} else if (segments == 2) {
        			micro = findSegment(version, index);
        			index += micro.length();
        			
        			if (index < version.length() && version.charAt(index) == '.') {
    				    while (index < version.length() - 1 && version.charAt(index) == '.') {
    					    index++;
    				    }
    			    }
        		}
        	}
    	    if (major != null && minor != null && micro != null) {
    	    	if (qualifier == null && index < version.length() - 1) {
    	    		qualifier = version.substring(index);
    	    	}
    	    	if (qualifier != null && qualifier.indexOf('.') != -1) { //$NON-NLS-1$
        	    	qualifier = qualifier.replace('.', '_'); //$NON-NLS-1$
    	    	}
    	    	break;
    	    }
        }
    	return new Version(Integer.parseInt(major), Integer.parseInt(minor), Integer.parseInt(micro), qualifier);
    }
    
    private String findSegment(String version, int beginIndex) {
		int endIndex = beginIndex;
		while (endIndex < version.length() && Character.isDigit(version.charAt(endIndex))) {
			endIndex++;
		}
		if (endIndex == beginIndex) {
			return Character.toString(version.charAt(beginIndex));
		} else {
			return version.substring(beginIndex, endIndex);
		}
    }

    public boolean finish() {
        CXFPersistentContext context = CXFCorePlugin.getDefault().getJava2WSContext();
        Map<String, CXFInstall> installs = context.getInstallations();
        CXFInstall install = CXFFactory.eINSTANCE.createCXFInstall();
        install.setVersion(cxfVersionText.getText().trim());
        install.setLocation(cxfHomeDirText.getText().trim());
        install.setType(cxfTypeText.getText().trim());
        installs.put(cxfRuntimeVersion, install);
        context.setInstallations(installs);
        if (isUpdateRequired(install)) {
            updateProjects(install);
        }
        return true;
    }

    public boolean isUpdateRequired(CXFInstall install) {
        if (cxfInstall == null) {
            return false;
        }
        if (!cxfInstall.getLocation().equals(install.getLocation())
                || !cxfInstall.getType().equals(install.getType())) {
            return true;
        }
        return false;
    }

    public void updateProjects(CXFInstall install) {
        try {
            Set<IFacetedProject> cxfProjects = ProjectFacetsManager.getFacetedProjects(ProjectFacetsManager.getProjectFacet("cxf.core"));
            Iterator<IFacetedProject> projIter = cxfProjects.iterator();
            while (projIter.hasNext()) {
                IFacetedProject cxfProject = projIter.next();
                String installedVersion = CXFCorePlugin.getDefault().getCXFRuntimeVersion(cxfProject.getProject());
                if (installedVersion.equals(install.getVersion())) {
                    ClasspathContainerInitializer classpathContainerInitializer = JavaCore.getClasspathContainerInitializer(
                            CXFCorePlugin.CXF_CLASSPATH_CONTAINER_ID);
                    if (classpathContainerInitializer != null) {
                        IPath containerPath = new Path(CXFCorePlugin.CXF_CLASSPATH_CONTAINER_ID);
                        IJavaProject javaProject = JavaCore.create(cxfProject.getProject());
                        CXFClasspathContainer cxfClasspathContainer = new CXFClasspathContainer(containerPath, javaProject);
                        classpathContainerInitializer.requestClasspathContainerUpdate(containerPath, javaProject,
                                cxfClasspathContainer);
                    }
                }
            }
        } catch (CoreException ce) {
            CXFUIPlugin.log(ce.getStatus());
        }
    }
}