package com.spring.common.validation;

import java.text.ParseException;
import java.util.Date;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.quartz.CronExpression;

/**
 * Cron 표현식의 유효성을 검사하는 제약 조건 검증기 클래스입니다.
 * 
 * <p>이 클래스는 Spring의 ConstraintValidator 인터페이스를 구현하여,
 * 주어진 문자열이 유효한 Cron 표현식인지 확인합니다.</p>
 * 
 * <p>유효한 Cron 표현식은 다음 유효성 검사를 통과해야 합니다:</p>
 * <ul>
 *   <li>Null 또는 빈 문자열이 아니어야 합니다.</li>
 *   <li>CronExpression.isValidExpression 메서드를 통해 유효한 표현식인지 확인해야 합니다.</li>
 *   <li>현재 시간 이후의 유효한 실행 시간을 가져올 수 있어야 합니다.</li>
 * </ul>
 * 
 * @author mindol
 * @version 1.0
 */
public class CronExpressionValidator implements ConstraintValidator<ValidCronExpression, String> {

    /**
     * 주어진 Cron 표현식의 유효성을 검사합니다.
     * 
     * <p>유효성 검사 과정에서 Cron 표현식이 null이거나 빈 문자열인 경우 false를 반환합니다.
     * 유효한 Cron 표현식인 경우, 다음 실행 시간을 확인하여 true 또는 false를 반환합니다.</p>
     * 
     * @param cronExpression 검사할 Cron 표현식
     * @param context 제약 조건 검증기 컨텍스트
     * @return 유효한 Cron 표현식인 경우 true, 그렇지 않으면 false
     */
    @Override
    public boolean isValid(String cronExpression, ConstraintValidatorContext context) {
        if (cronExpression == null || cronExpression.isEmpty()) {
            return false;
        }
        boolean result = false;
        if (CronExpression.isValidExpression(cronExpression)) {
            try {
                CronExpression targetExpression = new CronExpression(cronExpression);
                if (targetExpression.getNextValidTimeAfter(new Date(System.currentTimeMillis())) != null) {
                    result = true;
                }
            } catch (ParseException e) {
                result = false;
            }
        }
        return result;
    }

}
