package ru.yandex.qe.bus.javatime;

import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.TemporalAccessor;

import javax.ws.rs.ext.ParamConverter;

/**
 * @author Alexei Zakharov (ayza)
 */
public class LocalDateTimeParamConverter implements ParamConverter<LocalDateTime> {
  private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
      .append(DateTimeFormatter.ISO_LOCAL_DATE)
      .optionalStart()
      .appendLiteral('T')
      .append(DateTimeFormatter.ISO_LOCAL_TIME)
      .toFormatter();

  @Override
  public LocalDateTime fromString(String value) {
    try {
      TemporalAccessor obj = FORMATTER.parseBest(value, LocalDateTime::from, LocalDate::from);
      if (obj instanceof LocalDate) {
        return withZeroTime((LocalDate) obj);
      } else if (obj instanceof LocalDateTime) {
        return (LocalDateTime) obj;
      } else {
        throw new IllegalArgumentException("Unable to parse date-time: " + value);
      }
    } catch (DateTimeException e) {
      // let try basic ISO date or throw exception if doesn't match
      return withZeroTime(DateTimeFormatter.BASIC_ISO_DATE.parse(value, LocalDate::from));
    }
  }

  private LocalDateTime withZeroTime(LocalDate date) {
    return LocalDateTime.of(date, LocalTime.ofSecondOfDay(0));
  }

  @Override
  public String toString(LocalDateTime value) {
    return FORMATTER.format(value);
  }
}
