package org.apache.archiva.redback.components.scheduler;

/*
 * 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 org.apache.commons.lang.StringUtils;
import org.quartz.CronTrigger;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

/**
 * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
 *
 */
@Service
public final class CronExpressionValidator
{

    /**
     * Validates a cron expression.
     *
     * @param cronExpression The expression to validate
     * @return True is expression is valid
     */
    public boolean validate( String cronExpression )
    {
        try
        {
            String[] cronParams = StringUtils.split( cronExpression );

            if ( cronParams.length < 6 || cronParams.length > 7 )
            {
                return false;
            }

            CronTriggerImpl cronTrigger = new CronTriggerImpl();

            cronTrigger.setCronExpression( cronExpression );

            if ( cronParams[3].equals( "?" ) || cronParams[5].equals( "?" ) )
            {
                //Check seconds param
                if ( !checkSecondsField( cronParams[0] ) )
                {
                    return false;
                }

                //Check minutes param
                if ( !checkMinutesField( cronParams[1] ) )
                {
                    return false;
                }

                //Check hours param
                if ( !checkHoursField( cronParams[2] ) )
                {
                    return false;
                }

                //Check day-of-month param
                if ( !checkDayOfMonthField( cronParams[3] ) )
                {
                    return false;
                }

                //Check months param
                if ( !checkMonthsField( cronParams[4] ) )
                {
                    return false;
                }

                //Check day-of-week param
                if ( !checkDayOfWeekField( cronParams[5] ) )
                {
                    return false;
                }

                //Check year param
                if ( cronParams.length == 7 )
                {
                    if ( !checkYearField( cronParams[6] ) )
                    {
                        return false;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }
        catch ( ParseException e )
        {
            return false;
        }
    }

    private boolean checkSecondsField( String secondsField )
    {
        return checkField( secondsField, 0, 59 );
    }

    private boolean checkMinutesField( String minutesField )
    {
        return checkField( minutesField, 0, 59 );
    }

    private boolean checkHoursField( String hoursField )
    {
        return checkField( hoursField, 0, 23 );
    }

    private boolean checkDayOfMonthField( String dayOfMonthField )
    {
        if ( "?".equals( dayOfMonthField ) )
        {
            return true;
        }

        if ( dayOfMonthField.indexOf( "L" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfMonthField, "L", 1, 7, -1, -1 );
        }
        else if ( dayOfMonthField.indexOf( "W" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfMonthField, "W", 1, 31, -1, -1 );
        }
        else if ( dayOfMonthField.indexOf( "C" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfMonthField, "C", 1, 31, -1, -1 );
        }
        else
        {
            return checkField( dayOfMonthField, 1, 31 );
        }
    }

    private boolean checkMonthsField( String monthsField )
    {
        monthsField = StringUtils.replace( monthsField, "JAN", "1" );
        monthsField = StringUtils.replace( monthsField, "FEB", "2" );
        monthsField = StringUtils.replace( monthsField, "MAR", "3" );
        monthsField = StringUtils.replace( monthsField, "APR", "4" );
        monthsField = StringUtils.replace( monthsField, "MAY", "5" );
        monthsField = StringUtils.replace( monthsField, "JUN", "6" );
        monthsField = StringUtils.replace( monthsField, "JUL", "7" );
        monthsField = StringUtils.replace( monthsField, "AUG", "8" );
        monthsField = StringUtils.replace( monthsField, "SEP", "9" );
        monthsField = StringUtils.replace( monthsField, "OCT", "10" );
        monthsField = StringUtils.replace( monthsField, "NOV", "11" );
        monthsField = StringUtils.replace( monthsField, "DEC", "12" );

        return checkField( monthsField, 1, 31 );
    }

    private boolean checkDayOfWeekField( String dayOfWeekField )
    {
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "SUN", "1" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "MON", "2" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "TUE", "3" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "WED", "4" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "THU", "5" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "FRI", "6" );
        dayOfWeekField = StringUtils.replace( dayOfWeekField, "SAT", "7" );

        if ( "?".equals( dayOfWeekField ) )
        {
            return true;
        }

        if ( dayOfWeekField.indexOf( "L" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfWeekField, "L", 1, 7, -1, -1 );
        }
        else if ( dayOfWeekField.indexOf( "C" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfWeekField, "C", 1, 7, -1, -1 );
        }
        else if ( dayOfWeekField.indexOf( "#" ) >= 0 )
        {
            return checkFieldWithLetter( dayOfWeekField, "#", 1, 7, 1, 5 );
        }
        else
        {
            return checkField( dayOfWeekField, 1, 7 );
        }
    }

    private boolean checkYearField( String yearField )
    {
        return checkField( yearField, 1970, 2099 );
    }

    private boolean checkField( String secondsField, int minimal, int maximal )
    {
        if ( secondsField.indexOf( "-" ) > -1 )
        {
            String startValue = secondsField.substring( 0, secondsField.indexOf( "-" ) );
            String endValue = secondsField.substring( secondsField.indexOf( "-" ) + 1 );

            if ( !( checkIntValue( startValue, minimal, maximal ) && checkIntValue( endValue, minimal, maximal ) ) )
            {
                return false;
            }
            try
            {
                int startVal = Integer.parseInt( startValue );
                int endVal = Integer.parseInt( endValue );

                return endVal > startVal;

            }
            catch ( NumberFormatException e )
            {
                return false;
            }
        }
        else if ( secondsField.indexOf( "," ) > -1 )
        {
            return checkListField( secondsField, minimal, maximal );
        }
        else if ( secondsField.indexOf( "/" ) > -1 )
        {
            return checkIncrementField( secondsField, minimal, maximal );
        }
        else if ( secondsField.indexOf( "*" ) != -1 )
        {
            return true;
        }
        else
        {
            return checkIntValue( secondsField, minimal, maximal );
        }
    }

    private boolean checkFieldWithLetter( String value, String letter, int minimalBefore, int maximalBefore,
                                          int minimalAfter, int maximalAfter )
    {
        boolean canBeAlone = false;
        boolean canHaveIntBefore = false;
        boolean canHaveIntAfter = false;
        boolean mustHaveIntBefore = false;
        boolean mustHaveIntAfter = false;

        if ( "L".equals( letter ) )
        {
            canBeAlone = true;
            canHaveIntBefore = true;
            canHaveIntAfter = false;
            mustHaveIntBefore = false;
            mustHaveIntAfter = false;
        }
        if ( "W".equals( letter ) || "C".equals( letter ) )
        {
            canBeAlone = false;
            canHaveIntBefore = true;
            canHaveIntAfter = false;
            mustHaveIntBefore = true;
            mustHaveIntAfter = false;
        }
        if ( "#".equals( letter ) )
        {
            canBeAlone = false;
            canHaveIntBefore = true;
            canHaveIntAfter = true;
            mustHaveIntBefore = true;
            mustHaveIntAfter = true;
        }

        String beforeLetter = "";
        String afterLetter = "";

        if ( value.indexOf( letter ) >= 0 )
        {
            beforeLetter = value.substring( 0, value.indexOf( letter ) );
        }

        if ( !value.endsWith( letter ) )
        {
            afterLetter = value.substring( value.indexOf( letter ) + 1 );
        }

        if ( value.indexOf( letter ) >= 0 )
        {
            if ( letter.equals( value ) )
            {
                return canBeAlone;
            }

            if ( canHaveIntBefore )
            {
                if ( mustHaveIntBefore && beforeLetter.length() == 0 )
                {
                    return false;
                }

                if ( !checkIntValue( beforeLetter, minimalBefore, maximalBefore, true ) )
                {
                    return false;
                }
            }
            else
            {
                if ( beforeLetter.length() > 0 )
                {
                    return false;
                }
            }

            if ( canHaveIntAfter )
            {
                if ( mustHaveIntAfter && afterLetter.length() == 0 )
                {
                    return false;
                }

                if ( !checkIntValue( afterLetter, minimalAfter, maximalAfter, true ) )
                {
                    return false;
                }
            }
            else
            {
                if ( afterLetter.length() > 0 )
                {
                    return false;
                }
            }
        }

        return true;
    }

    private boolean checkIncrementField( String value, int minimal, int maximal )
    {
        String start = value.substring( 0, value.indexOf( "/" ) );

        String increment = value.substring( value.indexOf( "/" ) + 1 );

        if ( !"*".equals( start ) )
        {
            return checkIntValue( start, minimal, maximal ) && checkIntValue( increment, minimal, maximal, false );
        }
        else
        {
            return checkIntValue( increment, minimal, maximal );
        }
    }

    private boolean checkListField( String value, int minimal, int maximal )
    {
        StringTokenizer st = new StringTokenizer( value, "," );

        List values = new ArrayList();

        while ( st.hasMoreTokens() )
        {
            values.add( st.nextToken() );
        }

        int previousValue = -1;

        for ( Iterator i = values.iterator(); i.hasNext(); )
        {
            String currentValue = (String) i.next();

            if ( !checkIntValue( currentValue, minimal, maximal ) )
            {
                return false;
            }

            try
            {
                int val = Integer.parseInt( currentValue );

                if ( val <= previousValue )
                {
                    return false;
                }
                else
                {
                    previousValue = val;
                }
            }
            catch ( NumberFormatException e )
            {
                // we have always an int
            }
        }

        return true;
    }

    private boolean checkIntValue( String value, int minimal, int maximal )
    {
        return checkIntValue( value, minimal, maximal, true );
    }

    private static boolean checkIntValue( String value, int minimal, int maximal, boolean checkExtremity )
    {
        try
        {
            int val = Integer.parseInt( value );

            if ( checkExtremity )
            {
                if ( val < minimal || val > maximal )
                {
                    return false;
                }
            }

            return true;
        }
        catch ( NumberFormatException e )
        {
            return false;
        }
    }
}
