/*
 *  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.server.core.partition.impl.btree.gui;


import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.directory.server.i18n.I18n;
import org.apache.directory.server.xdbm.IndexEntry;
import org.apache.directory.server.xdbm.ForwardIndexEntry;
import org.apache.directory.server.xdbm.Index;
import org.apache.directory.shared.ldap.cursor.Cursor;
import org.apache.directory.shared.ldap.NotImplementedException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * A dialog showing index values.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$
 */
public class IndexDialog<K, O, ID> extends JDialog
{
    private static final Logger LOG = LoggerFactory.getLogger( IndexDialog.class );

    private static final long serialVersionUID = 3689917253680445238L;

    public static final String DEFAULT_CURSOR = "Default";
    public static final String EQUALITY_CURSOR = "Equality";
    public static final String GREATER_CURSOR = "Greater";
    public static final String LESS_CURSOR = "Less";
    public static final String REGEX_CURSOR = "Regex";

    private Panel mainPnl = new Panel();
    private JTabbedPane tabbedPane = new JTabbedPane();
    private JPanel listPnl = new JPanel();
    private JPanel cursorPnl = new JPanel();
    private JPanel resultsPnl = new JPanel();
    private JScrollPane jScrollPane2 = new JScrollPane();
    private JTable resultsTbl = new JTable();
    private JPanel buttonPnl = new JPanel();
    private JButton doneBut = new JButton();
    private JLabel jLabel1 = new JLabel();
    private JTextField keyText = new JTextField();
    private JLabel jLabel2 = new JLabel();
    private JButton scanBut = new JButton();

    private Index<K, O, ID> index = null;


    public IndexDialog( Frame parent, boolean modal, Index<K, O, ID> index )
    {
        super( parent, modal );
        this.index = index;
        initGUI();
    }


    public IndexDialog( Index<K, O, ID> index )
    {
        super();
        this.index = index;
        initGUI();
    }


    /**
     * This method is called from within the constructor to initialize the
     * form.
     */
    private void initGUI()
    {
        addWindowListener( new java.awt.event.WindowAdapter()
        {
            public void windowClosing( java.awt.event.WindowEvent evt )
            {
                closeDialog();
            }
        } );

        pack();
        setTitle( "Index On Attribute '" + index.getAttribute().getName() + "'" );
        setBounds( new java.awt.Rectangle( 0, 0, 512, 471 ) );
        getContentPane().add( mainPnl, java.awt.BorderLayout.CENTER );
        mainPnl.setLayout( new java.awt.BorderLayout() );
        mainPnl.add( tabbedPane, java.awt.BorderLayout.CENTER );
        tabbedPane.add( listPnl, "Listing" );
        listPnl.setLayout( new java.awt.GridBagLayout() );

        RadioButtonListener radioListener = new RadioButtonListener();
        JRadioButton radioDefault = new JRadioButton( DEFAULT_CURSOR );
        radioDefault.setActionCommand( DEFAULT_CURSOR );
        radioDefault.setSelected( true );
        radioDefault.addActionListener( radioListener );

        JRadioButton radioEquality = new JRadioButton( EQUALITY_CURSOR );
        radioEquality.setActionCommand( EQUALITY_CURSOR );
        radioEquality.addActionListener( radioListener );

        JRadioButton radioGreater = new JRadioButton( GREATER_CURSOR );
        radioGreater.setActionCommand( GREATER_CURSOR );
        radioGreater.addActionListener( radioListener );

        JRadioButton radioLess = new JRadioButton( LESS_CURSOR );
        radioLess.setActionCommand( LESS_CURSOR );
        radioLess.addActionListener( radioListener );

        JRadioButton radioRegex = new JRadioButton( REGEX_CURSOR );
        radioRegex.setActionCommand( REGEX_CURSOR );
        radioRegex.addActionListener( radioListener );

        ButtonGroup group = new ButtonGroup();
        group.add( radioDefault );
        group.add( radioEquality );
        group.add( radioGreater );
        group.add( radioLess );
        group.add( radioRegex );

        JPanel radioPanel = new JPanel();
        radioPanel.setLayout( new BoxLayout( radioPanel, BoxLayout.X_AXIS ) );
        radioPanel.add( radioDefault );
        radioPanel.add( radioEquality );
        radioPanel.add( radioGreater );
        radioPanel.add( radioLess );
        radioPanel.add( radioRegex );

        listPnl.add( cursorPnl, new java.awt.GridBagConstraints( 0, 0, 1, 1, 1.0, 0.15,
            java.awt.GridBagConstraints.NORTH, java.awt.GridBagConstraints.BOTH, new java.awt.Insets( 15, 0, 30, 0 ),
            0, 0 ) );
        listPnl.add( resultsPnl, new java.awt.GridBagConstraints( 0, 1, 1, 1, 1.0, 0.8,
            java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets( 0, 0, 0, 0 ), 0,
            0 ) );
        listPnl.add( buttonPnl, new java.awt.GridBagConstraints( 0, 2, 1, 1, 1.0, 0.05,
            java.awt.GridBagConstraints.CENTER, java.awt.GridBagConstraints.BOTH, new java.awt.Insets( 0, 0, 0, 0 ), 0,
            0 ) );
        cursorPnl.setLayout( new java.awt.GridBagLayout() );
        cursorPnl.setBorder( javax.swing.BorderFactory.createTitledBorder( javax.swing.BorderFactory.createLineBorder(
            new java.awt.Color( 153, 153, 153 ), 1 ), "Display Cursor Constraints",
            javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, new java.awt.Font(
                "SansSerif", 0, 14 ), new java.awt.Color( 60, 60, 60 ) ) );
        cursorPnl.add( jLabel1, new java.awt.GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0,
            java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 15, 0, 10 ), 0,
            0 ) );
        cursorPnl.add( keyText, new java.awt.GridBagConstraints( 1, 1, 1, 1, 0.4, 0.0,
            java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.BOTH, new java.awt.Insets( 5, 5, 5, 236 ), 0,
            0 ) );
        cursorPnl.add( jLabel2, new java.awt.GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0,
            java.awt.GridBagConstraints.WEST, java.awt.GridBagConstraints.NONE, new java.awt.Insets( 0, 15, 0, 10 ), 0,
            0 ) );
        cursorPnl.add( radioPanel,
            new java.awt.GridBagConstraints( 1, 0, 1, 1, 0.4, 0.0, java.awt.GridBagConstraints.WEST,
                java.awt.GridBagConstraints.NONE, new java.awt.Insets( 5, 5, 5, 0 ), 0, 0 ) );
        resultsPnl.setLayout( new java.awt.BorderLayout() );
        resultsPnl.setBorder( javax.swing.BorderFactory.createTitledBorder( javax.swing.BorderFactory.createLineBorder(
            new java.awt.Color( 153, 153, 153 ), 1 ), "Scan Results", javax.swing.border.TitledBorder.LEADING,
            javax.swing.border.TitledBorder.TOP, new java.awt.Font( "SansSerif", 0, 14 ), new java.awt.Color( 60, 60,
                60 ) ) );
        resultsPnl.add( jScrollPane2, java.awt.BorderLayout.CENTER );
        jScrollPane2.getViewport().add( resultsTbl );
        buttonPnl.setLayout( new java.awt.FlowLayout( java.awt.FlowLayout.CENTER, 15, 5 ) );
        buttonPnl.add( doneBut );
        buttonPnl.add( scanBut );
        doneBut.setText( "Done" );
        doneBut.addActionListener( new ActionListener()
        {
            public void actionPerformed( ActionEvent e )
            {
                closeDialog();
            }
        } );

        jLabel1.setText( "Key Constraint:" );
        keyText.setText( "" );
        keyText.setMinimumSize( new java.awt.Dimension( 130, 20 ) );
        keyText.setPreferredSize( new java.awt.Dimension( 130, 20 ) );
        keyText.setMaximumSize( new java.awt.Dimension( 130, 20 ) );
        keyText.setFont( new java.awt.Font( "SansSerif", java.awt.Font.PLAIN, 14 ) );
        keyText.setSize( new java.awt.Dimension( 130, 20 ) );
        jLabel2.setText( "Cursor Type:" );

        scanBut.setText( "Scan" );
        scanBut.addActionListener( new ActionListener()
        {
            public void actionPerformed( ActionEvent e )
            {
                //noinspection unchecked
                doScan( ( K ) keyText.getText(), selectedCursorType );
            }
        } );

        doScan( null, DEFAULT_CURSOR );
    }

    private String selectedCursorType = DEFAULT_CURSOR;

    class RadioButtonListener implements ActionListener
    {
        public void actionPerformed( ActionEvent e )
        {
            if ( e.getActionCommand().equals( DEFAULT_CURSOR ) )
            {
                selectedCursorType = DEFAULT_CURSOR;
            }
            else if ( e.getActionCommand().equals( EQUALITY_CURSOR ) )
            {
                selectedCursorType = EQUALITY_CURSOR;
            }
            else if ( e.getActionCommand().equals( GREATER_CURSOR ) )
            {
                selectedCursorType = GREATER_CURSOR;
            }
            else if ( e.getActionCommand().equals( LESS_CURSOR ) )
            {
                selectedCursorType = LESS_CURSOR;
            }
            else if ( e.getActionCommand().equals( REGEX_CURSOR ) )
            {
                selectedCursorType = REGEX_CURSOR;
            }
        }
    }


    private void closeDialog()
    {
        setVisible( false );
        dispose();
    }


    public boolean doScan( K key, String scanType )
    {
        if ( key == null && !scanType.equals( DEFAULT_CURSOR ) )
        {
            JOptionPane.showMessageDialog( null, "Cannot use a " + scanType + " scan type with a null key constraint.",
                "Missing Key Constraint", JOptionPane.ERROR_MESSAGE );
            return false;
        }

        Object[] cols = new Object[2];
        Object[] row;
        cols[0] = "Keys ( Attribute Value )";
        cols[1] = "Values ( Entry Id )";
        DefaultTableModel model = new DefaultTableModel( cols, 0 );
        int count = 0;

        try
        {
            Cursor<IndexEntry<K, O, ID>> list;

            if ( scanType.equals( EQUALITY_CURSOR ) )
            {
                list = index.forwardCursor( key );
                list.beforeFirst();
                while ( list.next() )
                {
                    IndexEntry<K, O, ID> rec = list.get();
                    row = new Object[2];
                    row[0] = rec.getValue();
                    row[1] = rec.getId();
                    model.addRow( row );
                    count++;
                }
            }
            else if ( scanType.equals( GREATER_CURSOR ) )
            {
                list = index.forwardCursor();
                ForwardIndexEntry<K, O, ID> entry = new ForwardIndexEntry<K, O, ID>();
                entry.setValue( key );
                list.before( entry );
                while ( list.next() )
                {
                    IndexEntry<K, O, ID> rec = list.get();
                    row = new Object[2];
                    row[0] = rec.getValue();
                    row[1] = rec.getId();
                    model.addRow( row );
                    count++;
                }
            }
            else if ( scanType.equals( LESS_CURSOR ) )
            {
                list = index.forwardCursor();
                ForwardIndexEntry<K, O, ID> entry = new ForwardIndexEntry<K, O, ID>();
                entry.setValue( key );
                list.after( entry );
                while ( list.previous() )
                {
                    IndexEntry<K, O, ID> rec = list.get();
                    row = new Object[2];
                    row[0] = rec.getValue();
                    row[1] = rec.getId();
                    model.addRow( row );
                    count++;
                }
            }
            else if ( scanType.equals( REGEX_CURSOR ) )
            {
                //                Pattern regex = StringTools.getRegex( key );
                //                int starIndex = key.indexOf( '*' );
                //
                //                if ( starIndex > 0 )
                //                {
                //                    String prefix = key.substring( 0, starIndex );
                //
                //                    if ( log.isDebugEnabled() )
                //                        log.debug( "Regex prefix = " + prefix );
                //
                //                    list = index.listIndices( regex, prefix );
                //                }
                //                else
                //                {
                //                    list = index.listIndices( regex );
                //                }
                throw new NotImplementedException();
            }
            else
            {
                list = index.forwardCursor();
                while ( list.next() )
                {
                    IndexEntry<K, O, ID> rec = list.get();
                    row = new Object[2];
                    row[0] = rec.getValue();
                    row[1] = rec.getId();
                    model.addRow( row );
                    count++;
                }
            }

            resultsTbl.setModel( model );
            resultsPnl.setBorder( BorderFactory.createTitledBorder( BorderFactory.createLineBorder( new Color( 153,
                153, 153 ), 1 ), "Scan Results: " + count, TitledBorder.LEADING, TitledBorder.TOP, new Font(
                "SansSerif", 0, 14 ), new Color( 60, 60, 60 ) ) );

            if ( isVisible() )
            {
                validate();
            }
        }
        catch ( Exception e )
        {
            String msg = ExceptionUtils.getStackTrace( e );

            if ( msg.length() > 1024 )
            {
                msg = msg.substring( 0, 1024 ) + "\n. . . TRUNCATED . . .";
            }

            msg = I18n.err( I18n.ERR_183, index.getAttribute(), scanType, key, msg );

            LOG.error( msg, e );
            JTextArea area = new JTextArea();
            area.setText( msg );
            JOptionPane.showMessageDialog( null, area, "Index Scan Error", JOptionPane.ERROR_MESSAGE );
            return false;
        }

        return true;
    }


    public static void show( Index index )
    {
        //noinspection unchecked
        IndexDialog dialog = new IndexDialog( index );
        dialog.setVisible( true );
    }
}
