
package de.ivu.elect.jee.presentation.dynamicform.converter;

import static org.apache.commons.lang3.StringUtils.trimToEmpty;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.DateTimeConverter;

public class AutoFormatDateTimeConverter extends DateTimeConverter {

  private final boolean pattern2DigitFutureYearConvertsToPastCentury;

  public AutoFormatDateTimeConverter() {
    this(false);
  }

  public AutoFormatDateTimeConverter(boolean pattern2DigitFutureYearConvertsToPastCentury) {
    super();

    this.pattern2DigitFutureYearConvertsToPastCentury = pattern2DigitFutureYearConvertsToPastCentury;
  }

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    String valueNormalized = trimToEmpty(value);

    try {
      return getAsObjectInternal(context, component, valueNormalized);
    } catch (Throwable actualCause) {
      try {
        return getAsObjectInternal(context, component, new AutoFormatDateFormatter(getPattern(), pattern2DigitFutureYearConvertsToPastCentury).tryAutoFormatValue(valueNormalized));
      } catch (Throwable ignored) {
        throw actualCause;
      }
    }
  }

  private Date getAsObjectInternal(FacesContext context, UIComponent component, String value) {
    Calendar calendar = getAsCalendarOrNull(context, component, value);

    // NOTE, dass das Problem an dieser Stelle ist, dass bei Verwendung von 'yyyy' und bei einer Eingabe als
    // zweistellige Jahreszahl '81' ein GÜLTIGES Datum (ohne Exception) mit dem Jahr '0081' geparsed wird.
    if (calendar != null && new SimpleDateFormat("yyyy").format(calendar.getTime()).startsWith("00")) {
      String pattern = getPattern();

      setPattern(pattern.replace("yyyy", "yy"));

      calendar = getAsCalendarOrNull(context, component, value);

      setPattern(pattern);

      if (calendar != null && pattern2DigitFutureYearConvertsToPastCentury) { // ELECTMUC-2429
        calendar = AutoFormatDateFormatter.convertFutureYearToPastCentury(calendar);
      }
    }

    if (calendar != null) {
      return calendar.getTime();
    }

    return null;
  }

  private Calendar getAsCalendarOrNull(FacesContext context, UIComponent component, String value) {
    Object object = super.getAsObject(context, component, value);

    if (object != null) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime((Date) object);

      return calendar;
    }

    return null;
  }
}
