/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */

package org.apache.directory.studio.ldapbrowser.common.wizards;


import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.name.Ava;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.api.ldap.model.name.Rdn;
import org.apache.directory.api.ldap.model.schema.AttributeType;
import org.apache.directory.studio.common.ui.widgets.BaseWidgetUtils;
import org.apache.directory.studio.common.ui.widgets.WidgetModifyEvent;
import org.apache.directory.studio.common.ui.widgets.WidgetModifyListener;
import org.apache.directory.studio.connection.ui.RunnableContextRunner;
import org.apache.directory.studio.ldapbrowser.common.BrowserCommonActivator;
import org.apache.directory.studio.ldapbrowser.common.BrowserCommonConstants;
import org.apache.directory.studio.ldapbrowser.common.widgets.DnBuilderWidget;
import org.apache.directory.studio.ldapbrowser.common.widgets.ListContentProposalProvider;
import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
import org.apache.directory.studio.ldapbrowser.core.jobs.ReadEntryRunnable;
import org.apache.directory.studio.ldapbrowser.core.model.IAttribute;
import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
import org.apache.directory.studio.ldapbrowser.core.model.IValue;
import org.apache.directory.studio.ldapbrowser.core.model.impl.Attribute;
import org.apache.directory.studio.ldapbrowser.core.model.impl.DummyEntry;
import org.apache.directory.studio.ldapbrowser.core.model.impl.Value;
import org.apache.directory.studio.ldapbrowser.core.model.schema.SchemaUtils;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.fieldassist.ComboContentAdapter;
import org.eclipse.jface.fieldassist.ContentProposalAdapter;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;


/**
 * The NewEntryDnWizardPage is used to compose the new entry's 
 * distinguished name.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class NewEntryDnWizardPage extends WizardPage implements WidgetModifyListener
{

    /** The wizard. */
    private NewEntryWizard wizard;

    /** The Dn builder widget. */
    private DnBuilderWidget dnBuilderWidget;

    /** The context entry Dn combo. */
    private Combo contextEntryDnCombo;

    /** The content proposal adapter for the context entry Dn combo. */
    private ContentProposalAdapter contextEntryDnComboCPA;


    /**
     * Creates a new instance of NewEntryDnWizardPage.
     * 
     * @param pageName the page name
     * @param wizard the wizard
     */
    public NewEntryDnWizardPage( String pageName, NewEntryWizard wizard )
    {
        super( pageName );
        setTitle( Messages.getString( "NewEntryDnWizardPage.DistinguishedName" ) ); //$NON-NLS-1$
        if ( wizard.isNewContextEntry() )
        {
            setDescription( Messages.getString( "NewEntryDnWizardPage.EnterDN" ) ); //$NON-NLS-1$
        }
        else
        {
            setDescription( Messages.getString( "NewEntryDnWizardPage.SelectParent" ) ); //$NON-NLS-1$
        }
        setImageDescriptor( BrowserCommonActivator.getDefault().getImageDescriptor(
            BrowserCommonConstants.IMG_ENTRY_WIZARD ) );
        setPageComplete( false );

        this.wizard = wizard;
    }


    /**
     * {@inheritDoc}
     */
    public void dispose()
    {
        if ( dnBuilderWidget != null )
        {
            dnBuilderWidget.removeWidgetModifyListener( this );
            dnBuilderWidget.dispose();
            dnBuilderWidget = null;
        }
        super.dispose();
    }


    /**
     * Validates the input fields.
     */
    private void validate()
    {
        if ( wizard.isNewContextEntry() && !"".equals( contextEntryDnCombo.getText() ) //$NON-NLS-1$
            && Dn.isValid( contextEntryDnCombo.getText() ) )
        {
            setPageComplete( true );
            saveState();
        }
        else if ( !wizard.isNewContextEntry() && dnBuilderWidget.getRdn() != null
            && dnBuilderWidget.getParentDn() != null )
        {
            setPageComplete( true );
            saveState();
        }
        else
        {
            setPageComplete( false );
        }
    }


    /**
     * Initializes the Dn builder widget with the Dn of
     * the prototype entry. Called when this page becomes visible.
     */
    private void loadState()
    {
        DummyEntry newEntry = wizard.getPrototypeEntry();

        if ( wizard.isNewContextEntry() )
        {
            IAttribute attribute = wizard.getSelectedConnection().getRootDSE().getAttribute(
                SchemaConstants.NAMING_CONTEXTS_AT );
            if ( attribute != null )
            {
                String[] values = attribute.getStringValues();

                // content proposals
                contextEntryDnComboCPA.setContentProposalProvider( new ListContentProposalProvider( values ) );

                // fill namingContext values into combo 
                contextEntryDnCombo.setItems( values );

                // preset combo text
                if ( Arrays.asList( values ).contains( newEntry.getDn().getName() ) )
                {
                    contextEntryDnCombo.setText( newEntry.getDn().getName() );
                }
            }
        }
        else
        {
            Collection<AttributeType> atds = SchemaUtils.getAllAttributeTypeDescriptions( newEntry );
            String[] attributeNames = SchemaUtils.getNames( atds ).toArray( ArrayUtils.EMPTY_STRING_ARRAY );

            Dn parentDn = null;

            boolean hasSelectedEntry = wizard.getSelectedEntry() != null;
            boolean newEntryParentDnNotNullOrEmpty = !Dn.isNullOrEmpty( newEntry.getDn().getParent() );

            if ( hasSelectedEntry )
            {
                boolean newEntryDnEqualsSelectedEntryDn = newEntry.getDn().equals( wizard.getSelectedEntry().getDn() );

                if ( newEntryDnEqualsSelectedEntryDn && newEntryParentDnNotNullOrEmpty )
                {
                    parentDn = newEntry.getDn().getParent();
                }
                else
                {
                    parentDn = wizard.getSelectedEntry().getDn();
                }
            }
            else if ( newEntryParentDnNotNullOrEmpty )
            {
                parentDn = newEntry.getDn().getParent();
            }

            Rdn rdn = newEntry.getRdn();

            dnBuilderWidget.setInput( wizard.getSelectedConnection(), attributeNames, rdn, parentDn );
        }
    }


    /**
     * Saves the Dn of the Dn builder widget to the prototype entry.
     */
    private void saveState()
    {
        DummyEntry newEntry = wizard.getPrototypeEntry();

        try
        {
            EventRegistry.suspendEventFiringInCurrentThread();

            // remove old Rdn
            if ( newEntry.getRdn().size() > 0 )
            {
                Iterator<Ava> atavIterator = newEntry.getRdn().iterator();
                while ( atavIterator.hasNext() )
                {
                    Ava atav = atavIterator.next();
                    IAttribute attribute = newEntry.getAttribute( atav.getType() );
                    if ( attribute != null )
                    {
                        IValue[] values = attribute.getValues();
                        for ( int v = 0; v < values.length; v++ )
                        {
                            if ( values[v].getStringValue().equals( atav.getValue().getNormalized() ) )
                            {
                                attribute.deleteValue( values[v] );
                            }
                        }

                        // If we have removed all the values of the attribute,
                        // then we also need to remove this attribute from the
                        // entry.
                        // This test has been added to fix DIRSTUDIO-222
                        if ( attribute.getValueSize() == 0 )
                        {
                            newEntry.deleteAttribute( attribute );
                        }
                    }
                }
            }

            // set new Dn
            Dn dn;

            if ( wizard.isNewContextEntry() )
            {
                try
                {
                    dn = new Dn( contextEntryDnCombo.getText() );
                }
                catch ( LdapInvalidDnException e )
                {
                    dn = Dn.EMPTY_DN;
                }
            }
            else
            {
                try
                {
                    dn = dnBuilderWidget.getParentDn().add( dnBuilderWidget.getRdn() );
                }
                catch ( LdapInvalidDnException lide )
                {
                    // Do nothing
                    dn = Dn.EMPTY_DN;
                }
            }
            newEntry.setDn( dn );

            // add new Rdn
            if ( dn.getRdn().size() > 0 )
            {
                Iterator<Ava> atavIterator = dn.getRdn().iterator();
                while ( atavIterator.hasNext() )
                {
                    Ava atav = atavIterator.next();
                    IAttribute rdnAttribute = newEntry.getAttribute( atav.getType() );
                    if ( rdnAttribute == null )
                    {
                        rdnAttribute = new Attribute( newEntry, atav.getType() );
                        newEntry.addAttribute( rdnAttribute );
                    }
                    Object rdnValue = atav.getValue().getNormalized();
                    String[] stringValues = rdnAttribute.getStringValues();
                    if ( !Arrays.asList( stringValues ).contains( rdnValue ) )
                    {
                        rdnAttribute.addValue( new Value( rdnAttribute, rdnValue ) );
                    }
                }
            }

        }
        finally
        {
            EventRegistry.resumeEventFiringInCurrentThread();
        }
    }


    /**
     * {@inheritDoc}
     * 
     * This implementation initializes Dn builder widghet with the
     * Dn of the protoype entry.
     */
    public void setVisible( boolean visible )
    {
        super.setVisible( visible );

        if ( visible )
        {
            loadState();
            validate();

            if ( wizard.isNewContextEntry() )
            {
                contextEntryDnCombo.setFocus();
            }
        }
    }


    /**
     * {@inheritDoc}
     * 
     * This implementation just checks if this page is complete. It 
     * doesn't call {@link #getNextPage()} to avoid unneeded 
     * invokings of {@link ReadEntryRunnable}s.
     */
    @Override
    public boolean canFlipToNextPage()
    {
        return isPageComplete();
    }


    /**
     * {@inheritDoc}
     * 
     * This implementation invokes a {@link ReadEntryRunnable} to check if an
     * entry with the composed Dn already exists.
     */
    @Override
    public IWizardPage getNextPage()
    {
        if ( !wizard.isNewContextEntry() )
        {
            dnBuilderWidget.validate();

            Rdn rdn = dnBuilderWidget.getRdn();
            Dn parentDn = dnBuilderWidget.getParentDn();

            try
            {
                final Dn dn = parentDn.add( rdn );

                // check if parent exists
                ReadEntryRunnable readEntryRunnable1 = new ReadEntryRunnable( wizard.getSelectedConnection(), parentDn );
                RunnableContextRunner.execute( readEntryRunnable1, getContainer(), false );
                IEntry parentEntry = readEntryRunnable1.getReadEntry();

                if ( parentEntry == null )
                {
                    getShell().getDisplay().syncExec( () -> 
                        {
                            MessageDialog
                                .openError( getShell(),
                                    Messages.getString( "NewEntryDnWizardPage.Error" ), //$NON-NLS-1$
                                    NLS
                                        .bind(
                                            Messages.getString( "NewEntryDnWizardPage.ParentDoesNotExist" ), dnBuilderWidget.getParentDn().toString() ) ); //$NON-NLS-1$
                        }
                    );

                    return null;
                }

                // check that new entry does not exists yet 
                ReadEntryRunnable readEntryRunnable2 = new ReadEntryRunnable( wizard.getSelectedConnection(), dn );
                RunnableContextRunner.execute( readEntryRunnable2, getContainer(), false );
                IEntry entry = readEntryRunnable2.getReadEntry();

                if ( entry != null )
                {
                    getShell().getDisplay().syncExec( () ->
                        {
                            MessageDialog
                                .openError(
                                    getShell(),
                                    Messages.getString( "NewEntryDnWizardPage.Error" ), NLS.bind( Messages.getString( "NewEntryDnWizardPage.EntryAlreadyExists" ), dn.toString() ) ); //$NON-NLS-1$ //$NON-NLS-2$
                        }
                    );

                    return null;
                }
            }
            catch ( LdapInvalidDnException lide )
            {
                return null;
            }
        }
        else
        {
            try
            {
                final Dn dn = new Dn( contextEntryDnCombo.getText() );

                // check that new entry does not exists yet 
                ReadEntryRunnable readEntryRunnable2 = new ReadEntryRunnable( wizard.getSelectedConnection(), dn );
                RunnableContextRunner.execute( readEntryRunnable2, getContainer(), false );
                IEntry entry = readEntryRunnable2.getReadEntry();
                if ( entry != null )
                {
                    getShell().getDisplay().syncExec( () ->
                        {
                            MessageDialog
                                .openError(
                                    getShell(),
                                    Messages.getString( "NewEntryDnWizardPage.Error" ), NLS.bind( Messages.getString( "NewEntryDnWizardPage.EntryAlreadyExists" ), dn.toString() ) ); //$NON-NLS-1$ //$NON-NLS-2$
                        }
                    );
                    
                    return null;
                }
            }
            catch ( LdapInvalidDnException e )
            {
                return null;
            }
        }

        return super.getNextPage();
    }


    /**
     * {@inheritDoc}
     */
    public void createControl( Composite parent )
    {
        if ( wizard.isNewContextEntry() )
        {
            // the combo
            Composite composite = BaseWidgetUtils.createColumnContainer( parent, 1, 1 );
            contextEntryDnCombo = BaseWidgetUtils.createCombo( composite, ArrayUtils.EMPTY_STRING_ARRAY, 0, 1 );
            contextEntryDnCombo.addModifyListener( event -> validate() );

            // attach content proposal behavior
            contextEntryDnComboCPA = new ContentProposalAdapter( contextEntryDnCombo, new ComboContentAdapter(), null,
                null, null );
            contextEntryDnComboCPA.setFilterStyle( ContentProposalAdapter.FILTER_NONE );
            contextEntryDnComboCPA.setProposalAcceptanceStyle( ContentProposalAdapter.PROPOSAL_REPLACE );

            setControl( composite );
        }
        else
        {
            dnBuilderWidget = new DnBuilderWidget( true, true );
            dnBuilderWidget.addWidgetModifyListener( this );
            Composite composite = dnBuilderWidget.createContents( parent );
            setControl( composite );
        }
    }


    /**
     * {@inheritDoc}
     */
    public void widgetModified( WidgetModifyEvent event )
    {
        validate();
    }


    /**
     * Saves the dialogs settings.
     */
    public void saveDialogSettings()
    {
        if ( !wizard.isNewContextEntry() )
        {
            dnBuilderWidget.saveDialogSettings();
        }
    }

}