/**
 * 
 */
package de.bstly.board.businesslogic;

import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAmount;
import java.time.temporal.TemporalUnit;

/**
 * The Class InstantHelper.
 */
public class InstantHelper {

	/**
	 * Plus.
	 *
	 * @param instant the instant
	 * @param amount the amount
	 * @return the instant
	 */
	public static Instant plus(Instant instant, TemporalAmount amount) {
		return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amount).toInstant();
	}

	/**
	 * Plus.
	 *
	 * @param instant the instant
	 * @param amountToAdd the amount to add
	 * @param unit the unit
	 * @return the instant
	 */
	public static Instant plus(Instant instant, long amountToAdd, TemporalUnit unit) {
		return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).plus(amountToAdd, unit).toInstant();
	}

	/**
	 * Minus.
	 *
	 * @param instant the instant
	 * @param amount the amount
	 * @return the instant
	 */
	public static Instant minus(Instant instant, TemporalAmount amount) {
		return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amount).toInstant();
	}

	/**
	 * Minus.
	 *
	 * @param instant the instant
	 * @param amountToAdd the amount to add
	 * @param unit the unit
	 * @return the instant
	 */
	public static Instant minus(Instant instant, long amountToAdd, TemporalUnit unit) {
		return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).minus(amountToAdd, unit)
				.toInstant();
	}

	/**
	 * Truncate.
	 *
	 * @param instant the instant
	 * @param unit the unit
	 * @return the instant
	 */
	public static Instant truncate(Instant instant, TemporalUnit unit) {
		if (ChronoUnit.YEARS.equals(unit)) {
			instant = instant.truncatedTo(ChronoUnit.DAYS);
			return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC)
					.with(ChronoField.DAY_OF_YEAR, 1L).toInstant();
		} else if (ChronoUnit.MONTHS.equals(unit)) {
			instant = instant.truncatedTo(ChronoUnit.DAYS);
			return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC)
					.with(ChronoField.DAY_OF_MONTH, 1L).toInstant();
		}

		return ZonedDateTime.ofInstant(instant, ZoneOffset.UTC).truncatedTo(unit).toInstant();
	}

}
