/*
 * 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.calcite.sql;

import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlOperandTypeChecker;
import org.apache.calcite.sql.type.SqlOperandTypeInference;
import org.apache.calcite.sql.type.SqlReturnTypeInference;
import org.apache.calcite.sql.type.SqlTypeUtil;
import org.apache.calcite.sql.validate.SqlMonotonicity;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;

import org.checkerframework.checker.nullness.qual.Nullable;

import java.math.BigDecimal;
import java.nio.charset.Charset;

import static org.apache.calcite.util.Static.RESOURCE;

import static java.util.Objects.requireNonNull;

/**
 * <code>SqlBinaryOperator</code> is a binary operator.
 */
public class SqlBinaryOperator extends SqlOperator {
  //~ Constructors -----------------------------------------------------------

  /**
   * Creates a SqlBinaryOperator.
   *
   * @param name                 Name of operator
   * @param kind                 Kind
   * @param prec                 Precedence
   * @param leftAssoc            Left-associativity
   * @param returnTypeInference  Strategy to infer return type
   * @param operandTypeInference Strategy to infer operand types
   * @param operandTypeChecker   Validator for operand types
   */
  public SqlBinaryOperator(
      String name,
      SqlKind kind,
      int prec,
      boolean leftAssoc,
      @Nullable SqlReturnTypeInference returnTypeInference,
      @Nullable SqlOperandTypeInference operandTypeInference,
      @Nullable SqlOperandTypeChecker operandTypeChecker) {
    super(
        name,
        kind,
        leftPrec(prec, leftAssoc),
        rightPrec(prec, leftAssoc),
        returnTypeInference,
        operandTypeInference,
        operandTypeChecker);
  }

  //~ Methods ----------------------------------------------------------------

  @Override public SqlSyntax getSyntax() {
    return SqlSyntax.BINARY;
  }

  @Override public @Nullable String getSignatureTemplate(final int operandsCount) {
    Util.discard(operandsCount);

    // op0 opname op1
    return "{1} {0} {2}";
  }

  /**
   * {@inheritDoc}
   *
   * <p>Returns true for most operators but false for the '.' operator;
   * consider
   *
   * <blockquote>
   * <pre>x.y + 5 * 6</pre>
   * </blockquote>
   */
  @Override boolean needsSpace() {
    return !getName().equals(".");
  }

  @Override public @Nullable SqlOperator reverse() {
    switch (kind) {
    case EQUALS:
    case NOT_EQUALS:
    case IS_DISTINCT_FROM:
    case IS_NOT_DISTINCT_FROM:
    case OR:
    case AND:
    case PLUS:
    case TIMES:
      return this;

    case GREATER_THAN:
      return SqlStdOperatorTable.LESS_THAN;
    case GREATER_THAN_OR_EQUAL:
      return SqlStdOperatorTable.LESS_THAN_OR_EQUAL;
    case LESS_THAN:
      return SqlStdOperatorTable.GREATER_THAN;
    case LESS_THAN_OR_EQUAL:
      return SqlStdOperatorTable.GREATER_THAN_OR_EQUAL;

    default:
      return null;
    }
  }

  @Override protected RelDataType adjustType(
      SqlValidator validator,
      final SqlCall call,
      RelDataType type) {
    return convertType(validator, call, type);
  }

  private RelDataType convertType(SqlValidator validator, SqlCall call, RelDataType type) {
    RelDataType operandType0 =
        validator.getValidatedNodeType(call.operand(0));
    RelDataType operandType1 =
        validator.getValidatedNodeType(call.operand(1));
    if (SqlTypeUtil.inCharFamily(operandType0)
        && SqlTypeUtil.inCharFamily(operandType1)) {
      Charset cs0 = operandType0.getCharset();
      Charset cs1 = operandType1.getCharset();
      assert (null != cs0) && (null != cs1)
          : "An implicit or explicit charset should have been set";
      if (!cs0.equals(cs1)) {
        throw validator.newValidationError(call,
            RESOURCE.incompatibleCharset(getName(), cs0.name(), cs1.name()));
      }

      SqlCollation collation0 = operandType0.getCollation();
      SqlCollation collation1 = operandType1.getCollation();
      assert (null != collation0) && (null != collation1)
          : "An implicit or explicit collation should have been set";

      // Validation will occur inside getCoercibilityDyadicOperator...
      SqlCollation resultCol =
          SqlCollation.getCoercibilityDyadicOperator(
              collation0,
              collation1);

      if (SqlTypeUtil.inCharFamily(type)) {
        type =
            validator.getTypeFactory()
                .createTypeWithCharsetAndCollation(
                    type,
                    type.getCharset(),
                    requireNonNull(resultCol, "resultCol"));
      }
    }
    return type;
  }

  @Override public RelDataType deriveType(
      SqlValidator validator,
      SqlValidatorScope scope,
      SqlCall call) {
    RelDataType type = super.deriveType(validator, scope, call);
    return convertType(validator, call, type);
  }

  @Override public SqlMonotonicity getMonotonicity(SqlOperatorBinding call) {
    if (getName().equals("/")) {
      if (call.isOperandNull(0, true)
          || call.isOperandNull(1, true)) {
        // null result => CONSTANT monotonicity
        return SqlMonotonicity.CONSTANT;
      }

      final SqlMonotonicity mono0 = call.getOperandMonotonicity(0);
      final SqlMonotonicity mono1 = call.getOperandMonotonicity(1);
      if (mono1 == SqlMonotonicity.CONSTANT) {
        if (call.isOperandLiteral(1, false)) {
          BigDecimal value = call.getOperandLiteralValue(1, BigDecimal.class);
          if (value == null) {
            return SqlMonotonicity.CONSTANT;
          }
          switch (value.signum()) {
          case -1:

            // mono / -ve constant --> reverse mono, unstrict
            return mono0.reverse().unstrict();
          case 0:

            // mono / zero --> constant (infinity!)
            return SqlMonotonicity.CONSTANT;
          default:

            // mono / +ve constant * mono1 --> mono, unstrict
            return mono0.unstrict();
          }
        }
      }
    }

    return super.getMonotonicity(call);
  }

  @Override public boolean validRexOperands(int count, Litmus litmus) {
    if (count != 2) {
      // Special exception for AND and OR.
      if ((this == SqlStdOperatorTable.AND
          || this == SqlStdOperatorTable.OR)
          && count > 2) {
        return true;
      }
      return litmus.fail("wrong operand count {} for {}", count, this);
    }
    return litmus.succeed();
  }
}
