package com.capgemini.framework.common;

import lombok.extern.slf4j.Slf4j;

import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

/**
 * This class is able to creates dates in a specific format (dd-MM-yyyy HH:mm).
 */
@Slf4j
public final class DateHelper {

  private static final String STD_YEAR_MONTH_FORMAT = "yyyy-MM";
  private static final String STD_DATE_FORMAT = "dd-MM-yyyy";

  private DateHelper() {
    // Private constructor to make this an utility class
  }

  /**
   * Converts a {@link Calendar} to a sql {@link Timestamp}.
   *
   * @param cal the {@link Calendar} to convert
   * @return the {@link Timestamp}
   */
  public static Timestamp toTimestamp(final Calendar cal) {
    return new Timestamp(cal.getTime().getTime());
  }

  /**
   * Extract current SQL date.
   *
   * @return the {@link Date}
   **/
  public static Date getCurrentSqlDate() {
    java.util.Date currentUtilDate = new java.util.Date();
    return new Date(currentUtilDate.getTime());
  }

  /**
   * Extract current SQL time stamp.
   *
   * @return the {@link Time}
   **/
  public static Timestamp getCurrentSqlTimestamp() {
    java.util.Date currentUtilDate = new java.util.Date();
    return new Timestamp(currentUtilDate.getTime());
  }

  /**
   * Compute the code for the current month period (year + "-" + month).
   *
   * @return the {@link Time}
   **/
  public static String getMonthPeriod() {
    return new SimpleDateFormat(STD_YEAR_MONTH_FORMAT).format(getCurrentSqlDate());
  }

  /**
   * Returns a Date that references today, at 00:00 am.
   *
   * @return the date of today with the following format (ex : 01-01-2015)
   */
  public static String getDate() {
    java.util.Date today = new java.util.Date();
    return new SimpleDateFormat(STD_DATE_FORMAT).format(today);
  }

  /**
   * Returns a Calendar representing the current date, offset by the number of days provided.
   *
   * @param nbDays nb ofdays to offset from today. psoitive: offset in the future.
   * @return a {@link Calendar}
   */
  public static Calendar offsetDays(final int nbDays) {
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.DAY_OF_MONTH, nbDays);
    return cal;
  }

  /**
   * Returns tomorrow, at 00:00m.
   *
   * @return date
   */
  public static String getDatePlusOne() {
    Calendar today = Calendar.getInstance();
    today.add(Calendar.DATE, 1);
    return today.get(Calendar.DATE) + "-" + (today.get(Calendar.MONTH) + 1) + "-" + today.get(Calendar.YEAR);
  }

  /**
   * Returns the reference date, offset by the provided number of days (positive in the future, negativ ein the past).
   *
   * @param dateReference the reference date
   * @return date +1
   */
  public static Calendar getDatePlusOneWithReferenceCalendar(final Calendar dateReference) {
    Calendar aujourdhui = Calendar.getInstance();
    if (dateReference != null) {
      aujourdhui.setTime(dateReference.getTime());
    }
    aujourdhui.add(Calendar.DATE, 1);
    return aujourdhui;
  }

  /**
   * Allow to findAll the date + 1 of a date which is entry in parameter.
   *
   * @param ref the reference date
   * @return date the input date, offset by the requested amount and formatted
   */
  public static String getDatePlusOneWithReferenceString(final String ref) {
    SimpleDateFormat curFormater = new SimpleDateFormat(STD_DATE_FORMAT);
    Calendar theDate = Calendar.getInstance();

    try {
      java.util.Date dateObj = curFormater.parse(ref);
      theDate.setTime(dateObj);
    }
    catch (ParseException e) {
      log.error("Unable to parse the Date : '" + ref + "', defaulting to tomorrow", e);
    }
    theDate.add(Calendar.DATE, 1);
    return theDate.get(Calendar.DATE) + "-" + (theDate.get(Calendar.MONTH) + 1) + "-" + theDate.get(Calendar.YEAR);
  }

  public static java.util.Date parseDate(final String ref) throws ParseException {
    return new SimpleDateFormat(STD_DATE_FORMAT).parse(ref);
  }
}
