package com.tibbo.aggregate.common.expression.function.date;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import com.tibbo.aggregate.common.Cres;
import com.tibbo.aggregate.common.expression.EvaluationEnvironment;
import com.tibbo.aggregate.common.expression.EvaluationException;
import com.tibbo.aggregate.common.expression.Evaluator;
import com.tibbo.aggregate.common.expression.Function;
import com.tibbo.aggregate.common.expression.function.AbstractFunction;
import com.tibbo.aggregate.common.util.DateUtils;
import org.apache.logging.log4j.util.Strings;

public class ParseDateFunction extends AbstractFunction
{
  public ParseDateFunction()
  {
    super("parseDate", Function.GROUP_DATE_TIME_PROCESSING, "String source, String pattern [, String timezone]", "String", Cres.get().getString("fDescParseDate"));
  }
  
  @Override
  public Object execute(Evaluator evaluator, EvaluationEnvironment environment, Object... parameters) throws EvaluationException
  {
    checkParameters(2, false, parameters);
    
    String source = parameters[0].toString();
    
    String pattern = parameters[1].toString();
    
    ZoneId zoneId = DateUtils.UTC_TIME_ZONE.toZoneId();
    
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);

    if (parameters.length > 2)
    {
      String zone = parameters[2].toString();
      if (!Strings.isEmpty(zone))
      {
        zoneId = ZoneId.of(zone);
      }
    }

    formatter = formatter.withZone(zoneId);

    try
    {
      return Date.from(ZonedDateTime.parse(source, formatter).toInstant());
    }
    catch (Exception ex)
    {
      try
      {
        return Date.from(LocalDate.parse(source, formatter)
            .atStartOfDay(formatter.getZone()).toInstant());
        
      }
      catch (Exception ex2)
      {
        throw new EvaluationException(ex.getMessage(), ex);
      }
    }
  }
}
