/*
 * Copyright 2017 The Mifos Initiative.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.mifos.individuallending.internal.service.schedule;

import javax.annotation.Nonnull;
import java.time.Duration;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Objects;

/**
 * @author Myrle Krantz
 */
public class Period implements Comparable<Period> {
  final private LocalDate beginDate;
  final private LocalDate endDate;
  final private boolean lastPeriod;

  public Period(final LocalDate beginDate, final LocalDate endDateExclusive) {
    this.beginDate = beginDate;
    this.endDate = endDateExclusive;
    this.lastPeriod = false;
  }

  public Period(final LocalDate beginDate, final LocalDate endDateExclusive, final boolean lastPeriod) {
    this.beginDate = beginDate;
    this.endDate = endDateExclusive;
    this.lastPeriod = lastPeriod;
  }

  public Period(final LocalDate beginDate, final int periodLength) {
    this.beginDate = beginDate;
    this.endDate = beginDate.plusDays(periodLength);
    this.lastPeriod = false;
  }

  public Period(final int periodLength, final LocalDate endDate) {
    this.beginDate = endDate.minusDays(periodLength);
    this.endDate = endDate;
    this.lastPeriod = false;
  }

  public LocalDate getBeginDate() {
    return beginDate;
  }

  public LocalDate getEndDate() {
    return endDate;
  }

  public boolean isLastPeriod() {
    return lastPeriod;
  }

  public Duration getDuration() {
    long days = beginDate.until(endDate, ChronoUnit.DAYS);
    return ChronoUnit.DAYS.getDuration().multipliedBy(days);
  }

  boolean containsDate(final LocalDate date) {
    return this.getBeginDate().compareTo(date) <= 0 && this.getEndDate().compareTo(date) > 0;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Period period = (Period) o;
    return lastPeriod == period.lastPeriod &&
        Objects.equals(beginDate, period.beginDate) &&
        Objects.equals(endDate, period.endDate);
  }

  @Override
  public int hashCode() {
    return Objects.hash(beginDate, endDate, lastPeriod);
  }

  @Override
  public int compareTo(@Nonnull Period o) {
    int comparison = compareNullableDates(endDate, o.endDate);
    if (comparison != 0)
      return comparison;

    comparison = compareNullableDates(beginDate, o.beginDate);
    if (comparison != 0)
      return comparison;

    if (lastPeriod == o.lastPeriod)
      return 0;
    else if (lastPeriod)
      return -1;
    else
      return 1;
  }

  @SuppressWarnings("ConstantConditions")
  private static int compareNullableDates(final LocalDate x, final LocalDate y) {
    if ((x == null) && (y == null))
      return 0;
    else if ((x == null) && (y != null))
      return -1;
    else if ((x != null) && (y == null))
      return 1;
    else
      return x.compareTo(y);
  }

  @Override
  public String toString() {
    return "Period{" +
        "beginDate=" + beginDate +
        ", endDate=" + endDate +
        ", lastPeriod=" + lastPeriod +
        '}';
  }
}
