package com.airlock.iam.base.infrastructure.validation;

import com.airlock.iam.elog.api.EDefaultLogType;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;

public class PageParameterValidator implements ConstraintValidator<ValidPageParameter, SanitizedPageParameter> {
   private static final ELogger LOG = ELoggerFactory.getLogger(PageParameterValidator.class);
   private final Provider<PageParameterLimits> pageParameterLimits;

   @Inject
   public PageParameterValidator(Provider<PageParameterLimits> pageParameterLimits) {
      this.pageParameterLimits = pageParameterLimits;
   }

   public void initialize(ValidPageParameter constraintAnnotation) {
      super.initialize(constraintAnnotation);
   }

   public boolean isValid(SanitizedPageParameter pageParameter, ConstraintValidatorContext context) {
      if (!this.isInRange(pageParameter)) {
         LOG.info(
            EDefaultLogType.GENERIC_LOG_TYPE,
            String.format(
               "REST request violates configured page limit. Query parameter page[limit]=%d not in range >= 0 and <= %d",
               pageParameter.getRequestedLimit(),
               ((PageParameterLimits)this.pageParameterLimits.get()).maxPageSize()
            )
         );
         return false;
      } else if (pageParameter.getOffset() < 0) {
         LOG.info(EDefaultLogType.GENERIC_LOG_TYPE, "Invalid offset: " + pageParameter.getOffset());
         return false;
      } else {
         return true;
      }
   }

   private boolean isInRange(SanitizedPageParameter pageParameter) {
      return pageParameter.getRequestedLimit() >= 0 && pageParameter.getRequestedLimit() <= ((PageParameterLimits)this.pageParameterLimits.get()).maxPageSize();
   }
}
