/*******************************************************************************
 * Copyright (c) 2010, 2021 Shane Clarke and Others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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.Platform;
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.Bundle;
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$
        }

        final String supportedPrefix = "reference:file:"; //$NON-NLS-1$
        Bundle activation = Platform.getBundle("javax.activation");
        if (activation != null && activation.getLocation().startsWith(supportedPrefix)) {
            cxfLib.add(activation.getLocation().substring(supportedPrefix.length()));
        }

        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());
        }
    }
}