package org.apache.commons.jcs.auxiliary.disk.jdbc.mysql;

/*
 * 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.
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.apache.commons.jcs.auxiliary.disk.jdbc.TableState;
import org.apache.commons.jcs.log.Log;
import org.apache.commons.jcs.log.LogManager;
import org.apache.commons.jcs.utils.timing.ElapsedTimer;

/**
 * The MySQL Table Optimizer can optimize MySQL tables. It knows how to optimize for MySQL databases
 * in particular and how to repair the table if it is corrupted in the process.
 * <p>
 * We will probably be able to abstract out a generic optimizer interface from this class in the
 * future.
 * <p>
 * @author Aaron Smuts
 */
public class MySQLTableOptimizer
{
    /** The logger */
    private static final Log log = LogManager.getLog( MySQLTableOptimizer.class );

    /** The data source */
    private DataSource dataSource = null;

    /** The name of the table. */
    private String tableName = null;

    /** optimizing, etc. */
    private TableState tableState;

    /**
     * This constructs an optimizer with the disk cacn properties.
     * <p>
     * @param attributes
     * @param tableState We mark the table status as optimizing when this is happening.
     * @param dataSource access to the database
     */
    public MySQLTableOptimizer( MySQLDiskCacheAttributes attributes, TableState tableState, DataSource dataSource )
    {
        setTableName( attributes.getTableName() );

        this.tableState = tableState;
        this.dataSource = dataSource;
    }

    /**
     * A scheduler will call this method. When it is called the table state is marked as optimizing.
     * TODO we need to verify that no deletions are running before we call optimize. We should wait
     * if a deletion is in progress.
     * <p>
     * This restores when there is an optimization error. The error output looks like this:
     *
     * <pre>
     *           mysql&gt; optimize table JCS_STORE_FLIGHT_OPTION_ITINERARY;
     *               +---------------------------------------------+----------+----------+---------------------+
     *               | Table                                       | Op       | Msg_type | Msg_text            |
     *               +---------------------------------------------+----------+----------+---------------------+
     *               | jcs_cache.JCS_STORE_FLIGHT_OPTION_ITINERARY | optimize | error    | 2 when fixing table |
     *               | jcs_cache.JCS_STORE_FLIGHT_OPTION_ITINERARY | optimize | status   | Operation failed    |
     *               +---------------------------------------------+----------+----------+---------------------+
     *               2 rows in set (51.78 sec)
     * </pre>
     *
     * A successful repair response looks like this:
     *
     * <pre>
     *        mysql&gt; REPAIR TABLE JCS_STORE_FLIGHT_OPTION_ITINERARY;
     *            +---------------------------------------------+--------+----------+----------------------------------------------+
     *            | Table                                       | Op     | Msg_type | Msg_text                                     |
     *            +---------------------------------------------+--------+----------+----------------------------------------------+
     *            | jcs_cache.JCS_STORE_FLIGHT_OPTION_ITINERARY | repair | error    | 2 when fixing table                          |
     *            | jcs_cache.JCS_STORE_FLIGHT_OPTION_ITINERARY | repair | warning  | Number of rows changed from 131276 to 260461 |
     *            | jcs_cache.JCS_STORE_FLIGHT_OPTION_ITINERARY | repair | status   | OK                                           |
     *            +---------------------------------------------+--------+----------+----------------------------------------------+
     *            3 rows in set (3 min 5.94 sec)
     * </pre>
     *
     * A successful optimization looks like this:
     *
     * <pre>
     *       mysql&gt; optimize table JCS_STORE_DEFAULT;
     *           +-----------------------------+----------+----------+----------+
     *           | Table                       | Op       | Msg_type | Msg_text |
     *           +-----------------------------+----------+----------+----------+
     *           | jcs_cache.JCS_STORE_DEFAULT | optimize | status   | OK       |
     *           +-----------------------------+----------+----------+----------+
     *           1 row in set (1.10 sec)
     * </pre>
     * @return true if it worked
     */
    public boolean optimizeTable()
    {
        ElapsedTimer timer = new ElapsedTimer();
        boolean success = false;

        if ( tableState.getState() == TableState.OPTIMIZATION_RUNNING )
        {
            log.warn( "Skipping optimization. Optimize was called, but the "
                    + "table state indicates that an optimization is currently running." );
            return false;
        }

        try
        {
            tableState.setState( TableState.OPTIMIZATION_RUNNING );
            log.info( "Optimizing table [{0}]", this.getTableName());

            try (Connection con = dataSource.getConnection())
            {
                // TEST

                try (Statement sStatement = con.createStatement())
                {
                    ResultSet rs = sStatement.executeQuery( "optimize table " + this.getTableName() );

                    // first row is error, then status
                    // if there is only one row in the result set, everything
                    // should be fine.
                    // This may be mysql version specific.
                    if ( rs.next() )
                    {
                        String status = rs.getString( "Msg_type" );
                        String message = rs.getString( "Msg_text" );

                        log.info( "Message Type: {0}", status );
                        log.info( "Message: {0}", message );

                        if ( "error".equals( status ) )
                        {
                            log.warn( "Optimization was in error. Will attempt "
                                    + "to repair the table. Message: {0}", message);

                            // try to repair the table.
                            success = repairTable( sStatement );
                        }
                        else
                        {
                            success = true;
                        }
                    }

                    // log the table status
                    String statusString = getTableStatus( sStatement );
                    log.info( "Table status after optimizing table [{0}]: {1}",
                            this.getTableName(), statusString );
                }
                catch ( SQLException e )
                {
                    log.error( "Problem optimizing table [{0}]",
                            this.getTableName(), e );
                    return false;
                }
            }
            catch ( SQLException e )
            {
                log.error( "Problem getting connection.", e );
            }
        }
        finally
        {
            tableState.setState( TableState.FREE );

            log.info( "Optimization of table [{0}] took {1} ms.",
                    () -> this.getTableName(), () -> timer.getElapsedTime() );
        }

        return success;
    }

    /**
     * This calls show table status and returns the result as a String.
     * <p>
     * @param sStatement
     * @return String
     * @throws SQLException
     */
    protected String getTableStatus( Statement sStatement )
        throws SQLException
    {
        ResultSet statusResultSet = sStatement.executeQuery( "show table status" );
        StringBuilder statusString = new StringBuilder();
        int numColumns = statusResultSet.getMetaData().getColumnCount();
        while ( statusResultSet.next() )
        {
            statusString.append( "\n" );
            for ( int i = 1; i <= numColumns; i++ )
            {
                statusString.append( statusResultSet.getMetaData().getColumnLabel( i ) + " ["
                    + statusResultSet.getString( i ) + "]  |  " );
            }
        }
        return statusString.toString();
    }

    /**
     * This is called if the optimization is in error.
     * <p>
     * It looks for "OK" in response. If it find "OK" as a message in any result set row, it returns
     * true. Otherwise we assume that the repair failed.
     * <p>
     * @param sStatement
     * @return true if successful
     * @throws SQLException
     */
    protected boolean repairTable( Statement sStatement )
        throws SQLException
    {
        boolean success = false;

        // if( message != null && message.indexOf( ) )
        ResultSet repairResult = sStatement.executeQuery( "repair table " + this.getTableName() );
        StringBuilder repairString = new StringBuilder();
        int numColumns = repairResult.getMetaData().getColumnCount();
        while ( repairResult.next() )
        {
            for ( int i = 1; i <= numColumns; i++ )
            {
                repairString.append( repairResult.getMetaData().getColumnLabel( i ) + " [" + repairResult.getString( i )
                    + "]  |  " );
            }

            String message = repairResult.getString( "Msg_text" );
            if ( "OK".equals( message ) )
            {
                success = true;
            }
        }
        log.info("{0}", repairString);

        if ( !success )
        {
            log.warn( "Failed to repair the table. {0}", repairString );
        }
        return success;
    }

    /**
     * @param tableName The tableName to set.
     */
    public void setTableName( String tableName )
    {
        this.tableName = tableName;
    }

    /**
     * @return Returns the tableName.
     */
    public String getTableName()
    {
        return tableName;
    }
}
