/*
 * Copyright (C) 2020 The Guava Authors
 *
 * Licensed 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 com.google.common.math;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.math.MathPreconditions.checkRoundingUnnecessary;

import com.google.common.annotations.GwtIncompatible;
import java.math.RoundingMode;

/**
 * Helper type to implement rounding {@code X} to a representable {@code double} value according to
 * a {@link RoundingMode}.
 */
@GwtIncompatible
abstract class ToDoubleRounder<X extends Number & Comparable<X>> {
  /**
   * Returns x rounded to either the greatest double less than or equal to the precise value of x,
   * or the least double greater than or equal to the precise value of x.
   */
  abstract double roundToDoubleArbitrarily(X x);

  /** Returns the sign of x: either -1, 0, or 1. */
  abstract int sign(X x);

  /** Returns d's value as an X, rounded with the specified mode. */
  abstract X toX(double d, RoundingMode mode);

  /** Returns a - b, guaranteed that both arguments are nonnegative. */
  abstract X minus(X a, X b);

  /** Rounds {@code x} to a {@code double}. */
  final double roundToDouble(X x, RoundingMode mode) {
    checkNotNull(x, "x");
    checkNotNull(mode, "mode");
    double roundArbitrarily = roundToDoubleArbitrarily(x);
    if (Double.isInfinite(roundArbitrarily)) {
      switch (mode) {
        case DOWN:
        case HALF_EVEN:
        case HALF_DOWN:
        case HALF_UP:
          return Double.MAX_VALUE * sign(x);
        case FLOOR:
          return (roundArbitrarily == Double.POSITIVE_INFINITY)
              ? Double.MAX_VALUE
              : Double.NEGATIVE_INFINITY;
        case CEILING:
          return (roundArbitrarily == Double.POSITIVE_INFINITY)
              ? Double.POSITIVE_INFINITY
              : -Double.MAX_VALUE;
        case UP:
          return roundArbitrarily;
        case UNNECESSARY:
          throw new ArithmeticException(x + " cannot be represented precisely as a double");
      }
    }
    X roundArbitrarilyAsX = toX(roundArbitrarily, RoundingMode.UNNECESSARY);
    int cmpXToRoundArbitrarily = x.compareTo(roundArbitrarilyAsX);
    switch (mode) {
      case UNNECESSARY:
        checkRoundingUnnecessary(cmpXToRoundArbitrarily == 0);
        return roundArbitrarily;
      case FLOOR:
        return (cmpXToRoundArbitrarily >= 0)
            ? roundArbitrarily
            : DoubleUtils.nextDown(roundArbitrarily);
      case CEILING:
        return (cmpXToRoundArbitrarily <= 0) ? roundArbitrarily : Math.nextUp(roundArbitrarily);
      case DOWN:
        if (sign(x) >= 0) {
          return (cmpXToRoundArbitrarily >= 0)
              ? roundArbitrarily
              : DoubleUtils.nextDown(roundArbitrarily);
        } else {
          return (cmpXToRoundArbitrarily <= 0) ? roundArbitrarily : Math.nextUp(roundArbitrarily);
        }
      case UP:
        if (sign(x) >= 0) {
          return (cmpXToRoundArbitrarily <= 0) ? roundArbitrarily : Math.nextUp(roundArbitrarily);
        } else {
          return (cmpXToRoundArbitrarily >= 0)
              ? roundArbitrarily
              : DoubleUtils.nextDown(roundArbitrarily);
        }
      case HALF_DOWN:
      case HALF_UP:
      case HALF_EVEN:
        {
          X roundFloor;
          double roundFloorAsDouble;
          X roundCeiling;
          double roundCeilingAsDouble;

          if (cmpXToRoundArbitrarily >= 0) {
            roundFloorAsDouble = roundArbitrarily;
            roundFloor = roundArbitrarilyAsX;
            roundCeilingAsDouble = Math.nextUp(roundArbitrarily);
            if (roundCeilingAsDouble == Double.POSITIVE_INFINITY) {
              return roundFloorAsDouble;
            }
            roundCeiling = toX(roundCeilingAsDouble, RoundingMode.CEILING);
          } else {
            roundCeilingAsDouble = roundArbitrarily;
            roundCeiling = roundArbitrarilyAsX;
            roundFloorAsDouble = DoubleUtils.nextDown(roundArbitrarily);
            if (roundFloorAsDouble == Double.NEGATIVE_INFINITY) {
              return roundCeilingAsDouble;
            }
            roundFloor = toX(roundFloorAsDouble, RoundingMode.FLOOR);
          }

          X deltaToFloor = minus(x, roundFloor);
          X deltaToCeiling = minus(roundCeiling, x);
          int diff = deltaToFloor.compareTo(deltaToCeiling);
          if (diff < 0) { // closer to floor
            return roundFloorAsDouble;
          } else if (diff > 0) { // closer to ceiling
            return roundCeilingAsDouble;
          }
          // halfway between the representable values; do the half-whatever logic
          switch (mode) {
            case HALF_EVEN:
              // roundFloorAsDouble and roundCeilingAsDouble are neighbors, so precisely
              // one of them should have an even long representation
              return ((Double.doubleToRawLongBits(roundFloorAsDouble) & 1L) == 0)
                  ? roundFloorAsDouble
                  : roundCeilingAsDouble;
            case HALF_DOWN:
              return (sign(x) >= 0) ? roundFloorAsDouble : roundCeilingAsDouble;
            case HALF_UP:
              return (sign(x) >= 0) ? roundCeilingAsDouble : roundFloorAsDouble;
            default:
              throw new AssertionError("impossible");
          }
        }
    }
    throw new AssertionError("impossible");
  }
}
