/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.druid.query.expression;

import com.google.common.base.Preconditions;
import org.apache.druid.common.config.NullHandling;
import org.apache.druid.java.util.common.DateTimes;
import org.apache.druid.java.util.common.IAE;
import org.apache.druid.java.util.common.granularity.PeriodGranularity;
import org.apache.druid.math.expr.Expr;
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Period;
import org.joda.time.chrono.ISOChronology;

import javax.annotation.Nullable;

public class ExprUtils
{
  static DateTimeZone toTimeZone(final Expr timeZoneArg)
  {
    if (!timeZoneArg.isLiteral()) {
      throw new IAE("Time zone must be a literal");
    }

    final Object literalValue = timeZoneArg.getLiteralValue();
    return literalValue == null ? DateTimeZone.UTC : DateTimes.inferTzFromString((String) literalValue);
  }

  static PeriodGranularity toPeriodGranularity(
      final Expr periodArg,
      @Nullable final Expr originArg,
      @Nullable final Expr timeZoneArg,
      final Expr.ObjectBinding bindings
  )
  {
    final Period period = new Period(periodArg.eval(bindings).asString());
    final DateTime origin;
    final DateTimeZone timeZone;

    if (timeZoneArg == null) {
      timeZone = null;
    } else {
      final String value = timeZoneArg.eval(bindings).asString();
      timeZone = value != null ? DateTimes.inferTzFromString(value) : null;
    }

    if (originArg == null) {
      origin = null;
    } else {
      Chronology chronology = timeZone == null ? ISOChronology.getInstanceUTC() : ISOChronology.getInstance(timeZone);
      final Object value = originArg.eval(bindings).value();
      if (value instanceof String && NullHandling.isNullOrEquivalent((String) value)) {
        // We get a blank string here, when sql compatible null handling is enabled
        // and expression contains empty string for for origin
        // e.g timestamp_floor(\"__time\",'PT1M','','UTC')
        origin = null;
      } else {
        origin = value != null ? new DateTime(value, chronology) : null;
      }
    }

    return new PeriodGranularity(period, origin, timeZone);
  }

  public static String createErrMsg(String functionName, String msg)
  {
    String prefix = "Function[" + functionName + "] ";
    return prefix + msg;
  }

  static void checkLiteralArgument(String functionName, Expr arg, String argName)
  {
    Preconditions.checkArgument(arg.isLiteral(), createErrMsg(functionName, argName + " arg must be a literal"));
  }

  /**
   * True if Expr is a string literal.
   *
   * In non-SQL-compliant null handling mode, this method will return true for null literals as well (because they are
   * treated equivalently to empty strings, and we cannot tell the difference.)
   *
   * In SQL-compliant null handling mode, this method will return true for actual strings only, not nulls.
   */
  static boolean isStringLiteral(final Expr expr)
  {
    return (expr.isLiteral() && expr.getLiteralValue() instanceof String)
           || (NullHandling.replaceWithDefault() && expr.isNullLiteral());
  }
}
