/*
 *  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.core.jobs;


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.directory.api.ldap.model.entry.DefaultAttribute;
import org.apache.directory.api.ldap.model.entry.DefaultModification;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.entry.Modification;
import org.apache.directory.api.ldap.model.entry.ModificationOperation;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.api.ldap.model.exception.LdapSchemaException;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.studio.common.core.jobs.StudioProgressMonitor;
import org.apache.directory.studio.connection.core.Connection;
import org.apache.directory.studio.connection.core.ConnectionCoreConstants;
import org.apache.directory.studio.connection.core.Controls;
import org.apache.directory.studio.connection.core.io.StudioLdapException;
import org.apache.directory.studio.connection.core.jobs.StudioConnectionBulkRunnableWithProgress;
import org.apache.directory.studio.ldapbrowser.core.BrowserCoreMessages;
import org.apache.directory.studio.ldapbrowser.core.events.BulkModificationEvent;
import org.apache.directory.studio.ldapbrowser.core.events.EventRegistry;
import org.apache.directory.studio.ldapbrowser.core.model.IBrowserConnection;
import org.apache.directory.studio.ldapbrowser.core.model.IEntry;
import org.apache.directory.studio.ldapbrowser.core.utils.ModelConverter;
import org.apache.directory.studio.ldapbrowser.core.utils.Utils;
import org.apache.directory.studio.ldifparser.LdifFormatParameters;
import org.apache.directory.studio.ldifparser.model.LdifEnumeration;
import org.apache.directory.studio.ldifparser.model.container.LdifChangeAddRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifChangeDeleteRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifChangeModDnRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifChangeModifyRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifChangeRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifContainer;
import org.apache.directory.studio.ldifparser.model.container.LdifContentRecord;
import org.apache.directory.studio.ldifparser.model.container.LdifModSpec;
import org.apache.directory.studio.ldifparser.model.container.LdifRecord;
import org.apache.directory.studio.ldifparser.model.lines.LdifAttrValLine;
import org.apache.directory.studio.ldifparser.model.lines.LdifCommentLine;
import org.apache.directory.studio.ldifparser.model.lines.LdifControlLine;
import org.apache.directory.studio.ldifparser.model.lines.LdifModSpecTypeLine;
import org.apache.directory.studio.ldifparser.parser.LdifParser;


/**
 * Runnable used to import an LDIF file.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class ImportLdifRunnable implements StudioConnectionBulkRunnableWithProgress
{
    /** The browser connection. */
    private IBrowserConnection browserConnection;

    /** The LDIF file. */
    private File ldifFile;

    /** The log file. */
    private File logFile;

    /** The update if entry exists flag. */
    private boolean updateIfEntryExists;

    /** The continue on error flag. */
    private boolean continueOnError;


    /**
     * Creates a new instance of ImportLdifRunnable.
     * 
     * @param browserConnection the browser connection
     * @param ldifFile the LDIF file
     * @param logFile the log file
     * @param updateIfEntryExists the update if entry exists flag
     * @param continueOnError the continue on error flag
     */
    public ImportLdifRunnable( IBrowserConnection browserConnection, File ldifFile, File logFile,
        boolean updateIfEntryExists, boolean continueOnError )
    {
        this.browserConnection = browserConnection;
        this.ldifFile = ldifFile;
        this.logFile = logFile;
        this.continueOnError = continueOnError;
        this.updateIfEntryExists = updateIfEntryExists;
    }


    /**
     * Creates a new instance of ImportLdifRunnable.
     * 
     * @param connection the connection
     * @param ldifFile the LDIF file
     * @param updateIfEntryExists the update if entry exists flag
     * @param continueOnError the continue on error flag
     */
    public ImportLdifRunnable( IBrowserConnection connection, File ldifFile, boolean updateIfEntryExists,
        boolean continueOnError )
    {
        this( connection, ldifFile, null, updateIfEntryExists, continueOnError );
    }


    /**
     * {@inheritDoc}
     */
    public Connection[] getConnections()
    {
        return new Connection[]
            { browserConnection.getConnection() };
    }


    /**
     * {@inheritDoc}
     */
    public String getName()
    {
        return BrowserCoreMessages.jobs__import_ldif_name;
    }


    /**
     * {@inheritDoc}
     */
    public Object[] getLockedObjects()
    {
        List<Object> l = new ArrayList<Object>();
        l.add( browserConnection.getUrl() + "_" + DigestUtils.shaHex( ldifFile.toString() ) ); //$NON-NLS-1$
        return l.toArray();
    }


    /**
     * {@inheritDoc}
     */
    public String getErrorMessage()
    {
        return BrowserCoreMessages.jobs__import_ldif_error;
    }


    /**
     * {@inheritDoc}
     */
    public void run( StudioProgressMonitor monitor )
    {
        monitor.beginTask( BrowserCoreMessages.jobs__import_ldif_task, 2 );
        monitor.reportProgress( " " ); //$NON-NLS-1$
        monitor.worked( 1 );

        try
        {
            Reader ldifReader = new BufferedReader( new FileReader( this.ldifFile ) );
            LdifParser parser = new LdifParser();
            LdifEnumeration enumeration = parser.parse( ldifReader );

            Writer logWriter;
            if ( this.logFile != null )
            {
                logWriter = new BufferedWriter( new FileWriter( this.logFile ) );
            }
            else
            {
                logWriter = new Writer()
                {
                    public void close() throws IOException
                    {
                    }


                    public void flush() throws IOException
                    {
                    }


                    public void write( char[] cbuf, int off, int len ) throws IOException
                    {
                    }
                };
            }

            importLdif( browserConnection, enumeration, logWriter, updateIfEntryExists, continueOnError, monitor );

            logWriter.close();
            ldifReader.close();
        }
        catch ( Exception e )
        {
            monitor.reportError( e );
        }
    }


    /**
     * {@inheritDoc}
     */
    public void runNotification( StudioProgressMonitor monitor )
    {
        EventRegistry.fireEntryUpdated( new BulkModificationEvent( browserConnection ), this );
    }


    /**
     * Imports the LDIF enumeration
     * 
     * @param browserConnection the browser connection
     * @param enumeration the LDIF enumeration
     * @param logWriter the log writer
     * @param updateIfEntryExists the update if entry exists flag
     * @param continueOnError the continue on error flag
     * @param monitor the progress monitor
     */
    static void importLdif( IBrowserConnection browserConnection, LdifEnumeration enumeration, Writer logWriter,
        boolean updateIfEntryExists, boolean continueOnError, StudioProgressMonitor monitor )
    {
        if ( browserConnection == null )
        {
            return;
        }

        StudioProgressMonitor dummyMonitor = new StudioProgressMonitor( monitor );
        int importedCount = 0;
        int errorCount = 0;
        try
        {
            while ( !monitor.isCanceled() && enumeration.hasNext() )
            {
                LdifContainer container = enumeration.next();

                if ( container instanceof LdifRecord )
                {
                    LdifRecord record = ( LdifRecord ) container;
                    try
                    {
                        dummyMonitor.reset();
                        importLdifRecord( browserConnection, record, updateIfEntryExists, dummyMonitor );
                        if ( dummyMonitor.errorsReported() )
                        {
                            errorCount++;
                            logModificationError( browserConnection, logWriter, record, dummyMonitor.getException(),
                                monitor );

                            if ( !continueOnError )
                            {
                                monitor.reportError( dummyMonitor.getException() );
                                return;
                            }
                        }
                        else
                        {
                            importedCount++;
                            logModification( browserConnection, logWriter, record, monitor );

                            // update cache and adjust attribute/children initialization flags
                            Dn dn = new Dn( record.getDnLine().getValueAsString() );
                            IEntry entry = browserConnection.getEntryFromCache( dn );
                            Dn parentDn = dn.getParent();
                            IEntry parentEntry = null;
                            while ( parentEntry == null && parentDn != null )
                            {
                                parentEntry = browserConnection.getEntryFromCache( parentDn );
                                parentDn = parentDn.getParent();
                            }

                            if ( record instanceof LdifChangeDeleteRecord )
                            {
                                if ( entry != null )
                                {
                                    entry.setAttributesInitialized( false );
                                    browserConnection.uncacheEntryRecursive( entry );
                                }
                                if ( parentEntry != null )
                                {
                                    parentEntry.setChildrenInitialized( false );
                                }
                            }
                            else if ( record instanceof LdifChangeModDnRecord )
                            {
                                if ( entry != null )
                                {
                                    entry.setAttributesInitialized( false );
                                    browserConnection.uncacheEntryRecursive( entry );
                                }
                                if ( parentEntry != null )
                                {
                                    parentEntry.setChildrenInitialized( false );
                                }
                                LdifChangeModDnRecord modDnRecord = ( LdifChangeModDnRecord ) record;
                                if ( modDnRecord.getNewsuperiorLine() != null )
                                {
                                    Dn newSuperiorDn = new Dn( modDnRecord.getNewsuperiorLine()
                                        .getValueAsString() );
                                    IEntry newSuperiorEntry = browserConnection.getEntryFromCache( newSuperiorDn );
                                    if ( newSuperiorEntry != null )
                                    {
                                        newSuperiorEntry.setChildrenInitialized( false );
                                    }
                                }
                            }
                            else if ( record instanceof LdifChangeAddRecord || record instanceof LdifContentRecord )
                            {
                                if ( entry != null )
                                {
                                    entry.setAttributesInitialized( false );
                                }
                                if ( parentEntry != null )
                                {
                                    parentEntry.setChildrenInitialized( false );
                                    parentEntry.setHasChildrenHint( true );
                                }
                            }
                            else
                            {
                                if ( entry != null )
                                {
                                    entry.setAttributesInitialized( false );
                                }
                            }
                        }
                    }
                    catch ( Exception e )
                    {
                        logModificationError( browserConnection, logWriter, record, e, monitor );
                        errorCount++;

                        if ( !continueOnError )
                        {
                            monitor.reportError( e );
                            return;
                        }
                    }

                    monitor.reportProgress( BrowserCoreMessages.bind(
                        BrowserCoreMessages.ldif__imported_n_entries_m_errors, new String[]
                            { "" + importedCount, "" + errorCount } ) ); //$NON-NLS-1$ //$NON-NLS-2$
                }
                else
                {
                    logWriter.write( container.toRawString() );
                }
            }

            if ( errorCount > 0 )
            {
                monitor.reportError( BrowserCoreMessages.bind( BrowserCoreMessages.ldif__n_errors_see_logfile,
                    new String[]
                        { "" + errorCount } ) ); //$NON-NLS-1$
            }
        }
        catch ( Exception e )
        {
            monitor.reportError( e );
        }
    }


    /**
     * Imports the LDIF record.
     * 
     * @param browserConnection the browser connection
     * @param record the LDIF record
     * @param updateIfEntryExists the update if entry exists flag
     * @param monitor the progress monitor
     * @throws LdapInvalidDnException
     */
    static void importLdifRecord( IBrowserConnection browserConnection, LdifRecord record, boolean updateIfEntryExists,
        StudioProgressMonitor monitor ) throws LdapException
    {
        if ( !record.isValid() )
        {
            throw new LdapSchemaException( BrowserCoreMessages.bind( BrowserCoreMessages.model__invalid_record,
                record.getInvalidString() ) );
        }

        String dn = record.getDnLine().getValueAsString();

        if ( record instanceof LdifContentRecord || record instanceof LdifChangeAddRecord )
        {
            IEntry dummyEntry;
            if ( record instanceof LdifContentRecord )
            {
                LdifContentRecord attrValRecord = ( LdifContentRecord ) record;
                try
                {
                    dummyEntry = ModelConverter.ldifContentRecordToEntry( attrValRecord, browserConnection );
                }
                catch ( LdapInvalidDnException e )
                {
                    monitor.reportError( e );
                    return;
                }
            }
            else
            {
                LdifChangeAddRecord changeAddRecord = ( LdifChangeAddRecord ) record;
                try
                {
                    dummyEntry = ModelConverter.ldifChangeAddRecordToEntry( changeAddRecord, browserConnection );
                }
                catch ( LdapInvalidDnException e )
                {
                    monitor.reportError( e );
                    return;
                }
            }

            Entry entry = ModelConverter.toLdapApiEntry( dummyEntry );
            browserConnection.getConnection().getConnectionWrapper()
                .createEntry( entry, getControls( record ), monitor, null );

            if ( monitor.errorsReported() && updateIfEntryExists
                && StudioLdapException.isEntryAlreadyExistsException( monitor.getException() ) )
            {
                // creation failed with Error 68, now try to update the existing entry
                monitor.reset();

                Collection<Modification> modifications = ModelConverter.toReplaceModifications( entry );
                browserConnection.getConnection().getConnectionWrapper()
                    .modifyEntry( new Dn( dn ), modifications, getControls( record ), monitor, null );
            }
        }
        else if ( record instanceof LdifChangeDeleteRecord )
        {
            LdifChangeDeleteRecord changeDeleteRecord = ( LdifChangeDeleteRecord ) record;
            browserConnection.getConnection().getConnectionWrapper()
                .deleteEntry( new Dn( dn ), getControls( changeDeleteRecord ), monitor, null );
        }
        else if ( record instanceof LdifChangeModifyRecord )
        {
            LdifChangeModifyRecord modifyRecord = ( LdifChangeModifyRecord ) record;
            LdifModSpec[] modSpecs = modifyRecord.getModSpecs();
            Collection<Modification> modifications = new ArrayList<>();
            for ( int ii = 0; ii < modSpecs.length; ii++ )
            {
                LdifModSpecTypeLine modSpecType = modSpecs[ii].getModSpecType();
                LdifAttrValLine[] attrVals = modSpecs[ii].getAttrVals();

                DefaultAttribute attribute = new DefaultAttribute( modSpecType.getUnfoldedAttributeDescription() );
                for ( int x = 0; x < attrVals.length; x++ )
                {
                    Object valueAsObject = attrVals[x].getValueAsObject();
                    if ( valueAsObject instanceof String )
                    {
                        attribute.add( ( String ) valueAsObject );
                    }
                    else if ( valueAsObject instanceof byte[] )
                    {
                        attribute.add( ( byte[] ) valueAsObject );
                    }
                }

                if ( modSpecType.isAdd() )
                {
                    modifications.add( new DefaultModification( ModificationOperation.ADD_ATTRIBUTE, attribute ) );
                }
                else if ( modSpecType.isDelete() )
                {
                    modifications.add( new DefaultModification( ModificationOperation.REMOVE_ATTRIBUTE, attribute ) );
                }
                else if ( modSpecType.isReplace() )
                {
                    modifications.add( new DefaultModification( ModificationOperation.REPLACE_ATTRIBUTE, attribute ) );
                }
            }

            browserConnection.getConnection().getConnectionWrapper()
                .modifyEntry( new Dn( dn ), modifications, getControls( modifyRecord ), monitor, null );
        }
        else if ( record instanceof LdifChangeModDnRecord )
        {
            LdifChangeModDnRecord modDnRecord = ( LdifChangeModDnRecord ) record;
            if ( modDnRecord.getNewrdnLine() != null && modDnRecord.getDeloldrdnLine() != null )
            {
                String newRdn = modDnRecord.getNewrdnLine().getValueAsString();
                boolean deleteOldRdn = modDnRecord.getDeloldrdnLine().isDeleteOldRdn();

                Dn newDn;
                if ( modDnRecord.getNewsuperiorLine() != null )
                {
                    newDn = new Dn( newRdn, modDnRecord.getNewsuperiorLine().getValueAsString() );
                }
                else
                {
                    Dn dnObject = new Dn( dn );
                    Dn parent = dnObject.getParent();
                    newDn = new Dn( newRdn, parent.getName() );
                }

                browserConnection.getConnection().getConnectionWrapper()
                    .renameEntry( new Dn( dn ), newDn, deleteOldRdn, getControls( modDnRecord ), monitor, null );
            }
        }
    }


    /**
     * Gets the controls.
     * 
     * @param record the LDIF record
     * 
     * @return the controls
     */
    private static Control[] getControls( LdifRecord record )
    {
        Control[] controls = null;
        if ( record instanceof LdifChangeRecord )
        {
            LdifChangeRecord changeRecord = ( LdifChangeRecord ) record;
            LdifControlLine[] controlLines = changeRecord.getControls();
            controls = new Control[controlLines.length];
            for ( int i = 0; i < controlLines.length; i++ )
            {
                LdifControlLine line = controlLines[i];
                controls[i] = Controls.create( line.getUnfoldedOid(), line.isCritical(),
                    line.getControlValueAsBinary() );
            }
        }
        return controls;
    }


    /**
     * Log a modification error to the given writer.
     * 
     * @param browserConnection the browser connection
     * @param logWriter the log writer
     * @param record the record
     * @param exception the exception
     * @param monitor the progress monitor
     */
    private static void logModificationError( IBrowserConnection browserConnection, Writer logWriter,
        LdifRecord record, Throwable exception, StudioProgressMonitor monitor )
    {
        try
        {
            LdifFormatParameters ldifFormatParameters = Utils.getLdifFormatParameters();
            DateFormat df = new SimpleDateFormat( ConnectionCoreConstants.DATEFORMAT );

            String errorComment = "#!ERROR " + exception.getMessage(); //$NON-NLS-1$
            errorComment = errorComment.replaceAll( "\r", " " ); //$NON-NLS-1$ //$NON-NLS-2$
            errorComment = errorComment.replaceAll( "\n", " " ); //$NON-NLS-1$ //$NON-NLS-2$
            LdifCommentLine errorCommentLine = LdifCommentLine.create( errorComment );

            logWriter.write( LdifCommentLine.create( "#!RESULT ERROR" ) //$NON-NLS-1$
                .toFormattedString( LdifFormatParameters.DEFAULT ) ); //$NON-NL LdifFormatParameters.DEFAULTS-1$
            logWriter
                .write( LdifCommentLine
                    .create(
                        "#!CONNECTION ldap://" + browserConnection.getConnection().getHost() + ":" + browserConnection.getConnection().getPort() ).toFormattedString( LdifFormatParameters.DEFAULT ) ); //$NON-NLS-1$ //$NON-NLS-2$
            logWriter.write( LdifCommentLine
                .create( "#!DATE " + df.format( new Date() ) ).toFormattedString( LdifFormatParameters.DEFAULT ) ); //$NON-NLS-1$
            logWriter.write( errorCommentLine.toFormattedString( LdifFormatParameters.DEFAULT ) );
            logWriter.write( record.toFormattedString( ldifFormatParameters ) );
        }
        catch ( IOException ioe )
        {
            monitor.reportError( BrowserCoreMessages.model__error_logging_modification, ioe );
        }
    }


    /**
     * Log a modification to the given writer.
     * 
     * @param browserConnection the browser connection
     * @param logWriter the log writer
     * @param record the record
     * @param monitor the progress monitor
     */
    private static void logModification( IBrowserConnection browserConnection, Writer logWriter, LdifRecord record,
        StudioProgressMonitor monitor )
    {
        try
        {
            LdifFormatParameters ldifFormatParameters = Utils.getLdifFormatParameters();
            DateFormat df = new SimpleDateFormat( ConnectionCoreConstants.DATEFORMAT );
            logWriter.write( LdifCommentLine.create( "#!RESULT OK" ).toFormattedString( ldifFormatParameters ) ); //$NON-NLS-1$
            logWriter
                .write( LdifCommentLine
                    .create(
                        "#!CONNECTION ldap://" + browserConnection.getConnection().getHost() + ":" + browserConnection.getConnection().getPort() ).toFormattedString( ldifFormatParameters ) ); //$NON-NLS-1$ //$NON-NLS-2$
            logWriter.write( LdifCommentLine
                .create( "#!DATE " + df.format( new Date() ) ).toFormattedString( ldifFormatParameters ) ); //$NON-NLS-1$
            logWriter.write( record.toFormattedString( ldifFormatParameters ) );
        }
        catch ( IOException ioe )
        {
            monitor.reportError( BrowserCoreMessages.model__error_logging_modification, ioe );
        }
    }
}
