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.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.TriggerBuilder;
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;
            }

            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withSchedule( CronScheduleBuilder.cronSchedule( cronExpression ) )
                .build();



            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 ( RuntimeException 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<String> values = new ArrayList<>();

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

        int previousValue = -1;

        for ( Iterator<String> i = values.iterator(); i.hasNext(); )
        {
            String currentValue = 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;
        }
    }
}
