package com.airlock.iam.common.application.query.restriction;

import com.airlock.iam.base.api.domain.model.store.query.DateField;
import com.airlock.iam.base.api.domain.model.store.query.Restriction;
import com.airlock.iam.common.api.domain.model.user.PersistentUser;
import com.airlock.iam.common.application.query.FilterData;
import com.airlock.iam.core.misc.util.DateRange;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Iterator;
import java.util.Optional;

public class DateRangeRestrictionProvider implements QueryFilterRestrictionProvider {
   private String property;
   private DateField<PersistentUser> field;
   private DateFormat dateFormat;
   private boolean isFromDate;

   @Override
   public Optional<Restriction> getRestriction(FilterData data) {
      String value = data.getCondition().getValue();
      if (!Strings.isNullOrEmpty(value) && value.contains("..")) {
         Iterable<String> values = Splitter.on("..").split(value);
         if (Iterables.size(values) != 2) {
            return Optional.empty();
         } else {
            Iterator<String> iterator = values.iterator();
            String fromDateString = iterator.next();
            String toDateString = iterator.next();
            DateRange range = this.dateRange(fromDateString, toDateString);
            if (this.isFromDate) {
               return range.getFromInstant() == null ? Optional.empty() : Optional.of(this.field.after(range.getFromDate()));
            } else {
               return range.getToInstant() == null ? Optional.empty() : Optional.of(this.field.before(range.getToDate()));
            }
         }
      } else {
         return Optional.empty();
      }
   }

   private DateRange dateRange(String fromDate, String toDate) {
      return new DateRange(this.toDate(fromDate), this.toDate(toDate));
   }

   private Date toDate(String date) {
      if (Strings.isNullOrEmpty(date)) {
         return null;
      }

      try {
         return this.dateFormat.parse(date);
      } catch (ParseException e) {
         return null;
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   public DateRangeRestrictionProvider(String property, DateField<PersistentUser> field, DateFormat dateFormat, boolean isFromDate) {
      this.property = property;
      this.field = field;
      this.dateFormat = dateFormat;
      this.isFromDate = isFromDate;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String getProperty() {
      return this.property;
   }
}
