/*******************************************************************************
 * Copyright (c) 2008 IONA Technologies PLC
 * 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:
 * IONA Technologies PLC - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.ws.internal.cxf.creation.ui.widgets;

import java.net.URI;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebService;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IAnnotation;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.window.Window;
import org.eclipse.jst.ws.annotations.core.utils.AnnotationUtils;
import org.eclipse.jst.ws.internal.cxf.core.model.Java2WSDataModel;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIMessages;
import org.eclipse.jst.ws.internal.cxf.creation.ui.CXFCreationUIPlugin;
import org.eclipse.jst.ws.internal.cxf.ui.widgets.Java2WSWidgetFactory;
import org.eclipse.jst.ws.internal.jaxws.core.JAXWSCoreMessages;
import org.eclipse.jst.ws.internal.jaxws.core.JAXWSCorePlugin;
import org.eclipse.jst.ws.jaxws.core.utils.JDTUtils;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
import org.eclipse.wst.command.internal.env.ui.widgets.SimpleWidgetDataContributor;
import org.eclipse.wst.command.internal.env.ui.widgets.WidgetDataEvents;

@SuppressWarnings("restriction")
public class Java2WSClassConfigWidget extends SimpleWidgetDataContributor {
    private IStatus JAVA_TYPE_NAME_STATUS = Status.OK_STATUS;
    private IStatus JAVA_TYPE_EXISTS_STATUS = Status.OK_STATUS;
    private IStatus SEI_SELECTION_STATUS = Status.OK_STATUS;

    private static final String NAME = "name";

    private int NUMBER_OF_PUBLIC_METHODS;
    private int NUMBER_OF_CHECKED_METHODS;
    private IMethod[] publicMethods;

    private Button useSEIButton;
    private Button selectSEIButton;
    private Button browseSEIButton;
    private Button extractSEIButton;

    private Combo selectSEICombo;
    private Text seiInterfaceNameText;

    private CheckboxTableViewer seiMembersToExtractTableViewer;
    private Table seiMembersToExtractTable;
    private Button selectAllButton;
    private Button deselectAllButton;

    private Java2WSDataModel model;
    private IType startingPointType;

    public Java2WSClassConfigWidget() {
    }

    public void setJava2WSDataModel(Java2WSDataModel model) {
        this.model = model;
    }

    public void setJavaStartingPointType(IType startingPointType) {
        this.startingPointType = startingPointType;
    }

    @Override
    public void internalize() {
        boolean useSEI = model.isUseServiceEndpointInterface();
        useSEIButton.setSelection(useSEI);
        selectSEIButton.setSelection(useSEI);
        selectSEIButton.setEnabled(useSEI);
        if (!useSEI) {
            selectSEICombo.deselectAll();
        }
        enableSelectSEIControls(useSEI);
        extractSEIButton.setSelection(false);
        extractSEIButton.setEnabled(useSEI);
        enableExtractSEIControls(useSEI);
        seiInterfaceNameText.setText("");
        seiMembersToExtractTableViewer.setAllChecked(false);
        NUMBER_OF_CHECKED_METHODS = 0;
        validateSEISelection();
    }

    @Override
    public WidgetDataEvents addControls(Composite parent, final Listener statusListener) {
        final Composite composite = new Composite(parent, SWT.NONE);
        GridLayout gridLayout = new GridLayout(3, false);
        composite.setLayout(gridLayout);

        GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
        composite.setLayoutData(gridData);

        useSEIButton = Java2WSWidgetFactory.createUseSEIButton(composite);
        useSEIButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                boolean useSEI = useSEIButton.getSelection();
                model.setUseServiceEndpointInterface(useSEI);
                selectSEIButton.setEnabled(useSEI);
                extractSEIButton.setEnabled(useSEI);
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
                if (!useSEI) {
                    model.setServiceEndpointInterfaceName("");

                    selectSEIButton.setSelection(false);
                    enableSelectSEIControls(false);

                    extractSEIButton.setSelection(false);
                    enableExtractSEIControls(false);
                }
            }

        });
        gridData = new GridData(SWT.FILL, SWT.CENTER, true, true);
        gridData.horizontalSpan = 3;
        useSEIButton.setLayoutData(gridData);

        Label paddingLabel = Java2WSWidgetFactory.createPaddingLabel(composite);
        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.horizontalSpan = 3;
        paddingLabel.setLayoutData(gridData);

        selectSEIButton = Java2WSWidgetFactory.createSelectSEIButton(composite);
        selectSEIButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                enableSelectSEIControls(selectSEIButton.getSelection());
                enableExtractSEIControls(!selectSEIButton.getSelection());
                if (selectSEIButton.getSelection() && selectSEICombo.getText().trim().length() > 0) {
                    updateSEISelectionStatus();
                    statusListener.handleEvent(null);
                }
            }
        });

        selectSEIButton.setSelection(false);
        selectSEIButton.setEnabled(false);
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        selectSEIButton.setLayoutData(gridData);

        selectSEICombo = Java2WSWidgetFactory.createSelectSEICombo(composite, model, startingPointType);
        selectSEICombo.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent event) {
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }
        });

        selectSEICombo.addModifyListener(new ModifyListener() {

            public void modifyText(ModifyEvent event) {
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }
        });

        gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
        gridData.horizontalSpan = 1;
        selectSEICombo.setLayoutData(gridData);

        browseSEIButton = Java2WSWidgetFactory.createBrowseButton(composite);

        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        gridData.horizontalSpan = 1;
        browseSEIButton.setLayoutData(gridData);

        browseSEIButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                ElementTreeSelectionDialog selectionDialog = Java2WSWidgetFactory.createElementTreeSelectionDialog(
                        composite.getShell(), CXFCreationUIMessages.JAVA2WS_SELECT_SEI_DIALOG_TITLE,
                        CXFCreationUIMessages.JAVA2WS_SELECT_SEI_DIALOG_DESCRIPTION,
                        JDTUtils.getJavaProject(model.getProjectName()), IJavaSearchConstants.INTERFACE);

                int returnCode = selectionDialog.open();
                if (returnCode == Window.OK) {
                    ICompilationUnit selectedCompilationUnit = (ICompilationUnit) selectionDialog.getFirstResult();
                    String selectedInterface = selectedCompilationUnit.findPrimaryType().getFullyQualifiedName();
                    List<String> seis = Arrays.asList(selectSEICombo.getItems());
                    if (!seis.contains(selectedInterface)) {
                        selectSEICombo.add(selectedInterface);
                    }
                    selectSEICombo.setText(selectedInterface);
                }
            }
        });

        paddingLabel = Java2WSWidgetFactory.createPaddingLabel(composite);
        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.horizontalSpan = 3;
        paddingLabel.setLayoutData(gridData);

        extractSEIButton = Java2WSWidgetFactory.createExtractSEIButton(composite);
        extractSEIButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                boolean extract = extractSEIButton.getSelection();
                model.setExtractInterface(extract);
                enableExtractSEIControls(extract);
                enableSelectSEIControls(!extract);
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }
        });
        extractSEIButton.setSelection(model.isExtractInterface());
        extractSEIButton.setEnabled(false);

        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        extractSEIButton.setLayoutData(gridData);

        seiInterfaceNameText = Java2WSWidgetFactory.createSEIInterfaceNameText(composite);
        seiInterfaceNameText.addModifyListener(new ModifyListener() {

            public void modifyText(ModifyEvent event) {
                if (extractSEIButton.getSelection()) {
                    String interfaceName = seiInterfaceNameText.getText();
                    String seiName = interfaceName;
                    String packageName = startingPointType.getPackageFragment().getElementName();
                    if (packageName.length() > 0) {
                        seiName = packageName + "." + interfaceName;
                    }
                    model.setServiceEndpointInterfaceName(seiName);

                    String compilationUnitName = interfaceName + ".java"; //$NON-NLS-1$
                    JAVA_TYPE_NAME_STATUS = JDTUtils.validateJavaTypeName(model.getProjectName(), interfaceName);
                    JAVA_TYPE_EXISTS_STATUS = checkTypeExists(startingPointType, compilationUnitName);
                    updateSEISelectionStatus();
                    statusListener.handleEvent(null);
                }
            }
        });

        gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
        gridData.horizontalSpan = 1;
        seiInterfaceNameText.setLayoutData(gridData);

        Java2WSWidgetFactory.createPaddingLabel(composite);
        Java2WSWidgetFactory.createPaddingLabel(composite);

        Java2WSWidgetFactory.createMemebersToExtractLabel(composite);

        Java2WSWidgetFactory.createPaddingLabel(composite);
        Java2WSWidgetFactory.createPaddingLabel(composite);

        seiMembersToExtractTableViewer = Java2WSWidgetFactory
                .createSEIMembersToExtractTableViewer(composite);
        seiMembersToExtractTable = seiMembersToExtractTableViewer.getTable();
        seiMembersToExtractTableViewer.addCheckStateListener(new ICheckStateListener() {

            public void checkStateChanged(CheckStateChangedEvent event) {
                Object[] checkedMethods = seiMembersToExtractTableViewer.getCheckedElements();

                Map<IMethod, Map<String, Boolean>> methodMap = new HashMap<IMethod, Map<String, Boolean>>();
                for (int i = 0; i < checkedMethods.length; i++) {
                    methodMap.put((IMethod)checkedMethods[i], model.getAnnotationMap());
                }
                model.setMethodMap(methodMap);

                NUMBER_OF_CHECKED_METHODS = checkedMethods.length;

                if (NUMBER_OF_CHECKED_METHODS < NUMBER_OF_PUBLIC_METHODS) {
                    selectAllButton.setEnabled(true);
                } else if (NUMBER_OF_CHECKED_METHODS == NUMBER_OF_PUBLIC_METHODS) {
                    selectAllButton.setEnabled(false);
                }

                if (NUMBER_OF_CHECKED_METHODS > 0) {
                    deselectAllButton.setEnabled(true);
                } else {
                    deselectAllButton.setEnabled(false);
                }
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }
        });
        gridData = new GridData(SWT.FILL, SWT.FILL, true, true);
        gridData.verticalSpan = 3;
        gridData.heightHint = 100;
        seiMembersToExtractTable.setLayoutData(gridData);

        selectAllButton = Java2WSWidgetFactory.createSelectAllButton(composite);
        selectAllButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                seiMembersToExtractTableViewer.setAllChecked(true);
                selectAllButton.setEnabled(false);
                deselectAllButton.setEnabled(true);

                TableItem[] checkedMethods = seiMembersToExtractTableViewer.getTable().getItems();
                for (int i = 0; i < checkedMethods.length; i++) {
                    TableItem tableItem = checkedMethods[i];
                    SelectionEvent selectionEvent = event;
                    selectionEvent.detail = SWT.CHECK;
                    selectionEvent.item = tableItem;
                    seiMembersToExtractTableViewer.handleSelect(selectionEvent);
                }
                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }

        });
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        selectAllButton.setLayoutData(gridData);

        Java2WSWidgetFactory.createPaddingLabel(composite);

        deselectAllButton = Java2WSWidgetFactory.createDeselectAllButton(composite);
        deselectAllButton.addSelectionListener(new SelectionAdapter() {

            @Override
            public void widgetSelected(SelectionEvent event) {
                seiMembersToExtractTableViewer.setAllChecked(false);
                selectAllButton.setEnabled(true);
                deselectAllButton.setEnabled(false);

                TableItem[] checkedMethods = seiMembersToExtractTableViewer.getTable().getItems();
                for (int i = 0; i < checkedMethods.length; i++) {
                    TableItem tableItem = checkedMethods[i];
                    SelectionEvent selectionEvent = event;
                    selectionEvent.detail = SWT.CHECK;
                    selectionEvent.item = tableItem;
                    seiMembersToExtractTableViewer.handleSelect(selectionEvent);
                }

                updateSEISelectionStatus();
                statusListener.handleEvent(null);
            }
        });
        gridData = new GridData(SWT.FILL, SWT.FILL, false, false);
        deselectAllButton.setLayoutData(gridData);

        publicMethods = JDTUtils.getPublicMethods(startingPointType);
        NUMBER_OF_PUBLIC_METHODS = publicMethods.length;
        seiMembersToExtractTableViewer.setInput(publicMethods);

        enableSelectSEIControls(false);
        enableExtractSEIControls(false);
        selectAllButton.setEnabled(false);
        deselectAllButton.setEnabled(false);

        if (model.isUseServiceEndpointInterface()) {
            if (selectSEICombo.indexOf(model.getServiceEndpointInterfaceName()) == -1) {
                selectSEICombo.add(model.getServiceEndpointInterfaceName());
            }
            selectSEICombo.setText(model.getServiceEndpointInterfaceName());
            model.setFullyQualifiedJavaInterfaceName(model.getServiceEndpointInterfaceName());
        }

        return this;
    }

    private void validateSEISelection() {
        if (!useSEIButton.getSelection()) {
            SEI_SELECTION_STATUS = Status.OK_STATUS;
            return;
        }
        IType seiType = JDTUtils.getType(model.getProjectName(), selectSEICombo.getText());
        if (seiType != null) {
            try {
                IMethod[] seiMethods = seiType.getMethods();
                for (IMethod seiMethod : seiMethods) {
                    IMethod[] implMethods = startingPointType.findMethods(seiMethod);
                    if (implMethods == null) {
                        SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                            CXFCreationUIMessages.bind(CXFCreationUIMessages.WEBSERVICE_ENPOINTINTERFACE_MUST_IMPLEMENT,
                                    getImplementsMessage(seiType, seiMethod)));
                        break;
                    } else {
                        SEI_SELECTION_STATUS = validateSEIAddition();
                    }
                }
                model.setServiceEndpointInterfaceName(selectSEICombo.getText());
                model.setFullyQualifiedJavaInterfaceName(selectSEICombo.getText());
            } catch (JavaModelException jme) {
                CXFCreationUIPlugin.log(jme.getStatus());
            }
        } else {
            SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                CXFCreationUIMessages.bind(CXFCreationUIMessages.WEBSERVICE_ENPOINTINTERFACE_NOT_FOUND,
                            selectSEICombo.getText()));
        }
    }

    private String getImplementsMessage(IType seiType, IMethod seiMethod) {
        StringBuilder message = new StringBuilder(seiType.getElementName());
        message.append("."); //$NON-NLS-1$
        message.append(seiMethod.getElementName());
        message.append("("); //$NON-NLS-1$
        String[] parameterTypes = seiMethod.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            String parameterType = Signature.toString(parameterTypes[i]);
            message.append(parameterType);
            if (i < parameterTypes.length - 1) {
                message.append(", "); //$NON-NLS-1$
            }
        }
        message.append(")"); //$NON-NLS-1$
        return message.toString();
    }

    private IStatus validateSEIAddition() {
        IStatus status = Status.OK_STATUS;
        try {
            IAnnotation webService = AnnotationUtils.getAnnotation(WebService.class, startingPointType);
            if (webService != null) {
                Object name = AnnotationUtils.getAnnotationValue(webService, NAME);
                if (name != null) {
                    status = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                            CXFCreationUIMessages.JAVA2WS_SELECT_SEI_WEBSERVICE_NAME_ATTRIBUTE_PRESENT);
                }
            }
        } catch (JavaModelException jme) {
            CXFCreationUIPlugin.log(jme.getStatus());
        }
        return status;
    }

    public void enableSelectSEIControls(boolean enable) {
        selectSEICombo.setEnabled(enable);
        browseSEIButton.setEnabled(enable);
    }

    public void enableExtractSEIControls(boolean enable) {
        seiInterfaceNameText.setEnabled(enable);
        seiMembersToExtractTable.setEnabled(enable);
        if (enable && (NUMBER_OF_CHECKED_METHODS < NUMBER_OF_PUBLIC_METHODS)) {
            selectAllButton.setEnabled(true);
        }

        if (enable && (NUMBER_OF_CHECKED_METHODS > 0)) {
            deselectAllButton.setEnabled(true);
        }

        if (!enable) {
            selectAllButton.setEnabled(false);
            deselectAllButton.setEnabled(false);
        }
    }

    @Override
    public IStatus getStatus() {
        return findMostSevere();
    }

    private void updateSEISelectionStatus() {
        if (useSEIButton.getSelection()) {
            if (!selectSEIButton.getSelection() && !extractSEIButton.getSelection()) {
                SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                        CXFCreationUIMessages.JAVA2WS_SELECT_SEI_OPTION);
            }

            if (selectSEIButton.getSelection() && selectSEICombo.getText().length() == 0) {
                SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                        CXFCreationUIMessages.JAVA2WS_SELECT_SEI_MESSAGE);
            } else if (selectSEIButton.getSelection() && selectSEICombo.getText().length() > 0) {
                validateSEISelection();
            }

            if (extractSEIButton.getSelection() && seiInterfaceNameText.getText().trim().length() == 0) {
                SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                        CXFCreationUIMessages.JAVA2WS_ENTER_SEI_NAME);
            } else if (extractSEIButton.getSelection() && NUMBER_OF_PUBLIC_METHODS > 0
                    && NUMBER_OF_CHECKED_METHODS == 0) {
                SEI_SELECTION_STATUS = new Status(IStatus.ERROR, CXFCreationUIPlugin.PLUGIN_ID,
                        CXFCreationUIMessages.bind(
                                CXFCreationUIMessages.JAVA2WS_SELECT_SEI_EXTRACTED_METHODS,
                                startingPointType.getElementName()));
            } else if (extractSEIButton.getSelection() && seiInterfaceNameText.getText().trim().length() > 0
                    && NUMBER_OF_PUBLIC_METHODS > 0 && NUMBER_OF_CHECKED_METHODS > 0) {
                SEI_SELECTION_STATUS = Status.OK_STATUS;
            }

        } else {
            SEI_SELECTION_STATUS = Status.OK_STATUS;
            JAVA_TYPE_NAME_STATUS = Status.OK_STATUS;
            JAVA_TYPE_EXISTS_STATUS = Status.OK_STATUS;
        }
    }

    private IStatus findMostSevere() {
        if (JAVA_TYPE_NAME_STATUS.matches(IStatus.ERROR)) {
            return JAVA_TYPE_NAME_STATUS;
        }
        if (JAVA_TYPE_EXISTS_STATUS.matches(IStatus.ERROR)) {
            return JAVA_TYPE_EXISTS_STATUS;
        }
        if (SEI_SELECTION_STATUS.matches(IStatus.ERROR)) {
            return SEI_SELECTION_STATUS;
        }

        if (SEI_SELECTION_STATUS.getSeverity() >= JAVA_TYPE_NAME_STATUS.getSeverity()) {
            return SEI_SELECTION_STATUS;
        }

        if (JAVA_TYPE_EXISTS_STATUS.getSeverity() >= JAVA_TYPE_NAME_STATUS.getSeverity()) {
            return JAVA_TYPE_EXISTS_STATUS;
        }

        return JAVA_TYPE_NAME_STATUS;
    }

    public IStatus checkTypeExists(IType type, String compilationUnitName) {
        compilationUnitName = compilationUnitName.trim();

        IPackageFragment packageFragment = type.getPackageFragment();
        ICompilationUnit compilationUnit = packageFragment.getCompilationUnit(compilationUnitName);
        IResource resource = compilationUnit.getResource();

        if (resource.exists()) {
            return new Status(IStatus.ERROR, JAXWSCorePlugin.PLUGIN_ID, JAXWSCoreMessages
                    .bind(JAXWSCoreMessages.TYPE_WITH_NAME_ALREADY_EXISTS, new Object[] {
                            compilationUnitName, packageFragment.getElementName() }));
        }
        URI location = resource.getLocationURI();
        if (location != null) {
            try {
                IFileStore fileStore = EFS.getStore(location);
                if (fileStore.fetchInfo().exists()) {
                    return new Status(IStatus.ERROR, JAXWSCorePlugin.PLUGIN_ID,
                            JAXWSCoreMessages.TYPE_NAME_DIFFERENT_CASE_EXISTS);
                }
            } catch (CoreException ce) {
                JAXWSCorePlugin.log(ce.getStatus());
            }
        }
        return Status.OK_STATUS;
    }
}
