/*
 * 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;
  }

  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 +
        '}';
  }
}
