/*
 * Copyright (C) 2007 Google Inc.
 *
 * 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.inject.internal.util;

import java.util.Collection;
import java.util.NoSuchElementException;

/**
 * Simple static methods to be called at the start of your own methods to verify
 * correct arguments and state. This allows constructs such as
 * <pre>
 *     if (count <= 0) {
 *       throw new IllegalArgumentException("must be positive: " + count);
 *     }</pre>
 *
 * to be replaced with the more compact
 * <pre>
 *     checkArgument(count > 0, "must be positive: %s", count);</pre>
 *
 * Note that the sense of the expression is inverted; with {@code Preconditions}
 * you declare what you expect to be <i>true</i>, just as you do with an
 * <a href="http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html">
 * {@code assert}</a> or a JUnit {@code assertTrue()} call.
 *
 * <p>Take care not to confuse precondition checking with other similar types
 * of checks! Precondition exceptions -- including those provided here, but also
 * {@link IndexOutOfBoundsException}, {@link NoSuchElementException}, {@link
 * UnsupportedOperationException} and others -- are used to signal that the
 * <i>calling method</i> has made an error. This tells the caller that it should
 * not have invoked the method when it did, with the arguments it did, or
 * perhaps <i>ever</i>. Postcondition or other invariant failures should not
 * throw these types of exceptions.
 *
 * <p><b>Note:</b> The methods of the {@code Preconditions} class are highly
 * unusual in one way: they are <i>supposed to</i> throw exceptions, and promise
 * in their specifications to do so even when given perfectly valid input. That
 * is, {@code null} is a valid parameter to the method {@link
 * #checkNotNull(Object)} -- and technically this parameter could be even marked
 * as {@link com.google.inject.internal.Nullable} -- yet the method will still throw an exception anyway,
 * because that's what its contract says to do.
 * 
 * <p>This class may be used with the Google Web Toolkit (GWT).
 *
 * @author Kevin Bourrillion
 */
public final class Preconditions {
  private Preconditions() {}

  /**
   * Ensures the truth of an expression involving one or more parameters to the
   * calling method.
   *
   * @param expression a boolean expression
   * @throws IllegalArgumentException if {@code expression} is false
   */
  public static void checkArgument(boolean expression) {
    if (!expression) {
      throw new IllegalArgumentException();
    }
  }

  /**
   * Ensures the truth of an expression involving one or more parameters to the
   * calling method.
   *
   * @param expression a boolean expression
   * @param errorMessage the exception message to use if the check fails; will
   *     be converted to a string using {@link String#valueOf(Object)}
   * @throws IllegalArgumentException if {@code expression} is false
   */
  public static void checkArgument(boolean expression, Object errorMessage) {
    if (!expression) {
      throw new IllegalArgumentException(String.valueOf(errorMessage));
    }
  }

  /**
   * Ensures the truth of an expression involving one or more parameters to the
   * calling method.
   *
   * @param expression a boolean expression
   * @param errorMessageTemplate a template for the exception message should the
   *     check fail. The message is formed by replacing each {@code %s}
   *     placeholder in the template with an argument. These are matched by
   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
   *     Unmatched arguments will be appended to the formatted message in square
   *     braces. Unmatched placeholders will be left as-is.
   * @param errorMessageArgs the arguments to be substituted into the message
   *     template. Arguments are converted to strings using
   *     {@link String#valueOf(Object)}.
   * @throws IllegalArgumentException if {@code expression} is false
   * @throws NullPointerException if the check fails and either {@code
   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
   *     this happen)
   */
  public static void checkArgument(boolean expression,
      String errorMessageTemplate, Object... errorMessageArgs) {
    if (!expression) {
      throw new IllegalArgumentException(
          format(errorMessageTemplate, errorMessageArgs));
    }
  }

  /**
   * Ensures the truth of an expression involving the state of the calling
   * instance, but not involving any parameters to the calling method.
   *
   * @param expression a boolean expression
   * @throws IllegalStateException if {@code expression} is false
   */
  public static void checkState(boolean expression) {
    if (!expression) {
      throw new IllegalStateException();
    }
  }

  /**
   * Ensures the truth of an expression involving the state of the calling
   * instance, but not involving any parameters to the calling method.
   *
   * @param expression a boolean expression
   * @param errorMessage the exception message to use if the check fails; will
   *     be converted to a string using {@link String#valueOf(Object)}
   * @throws IllegalStateException if {@code expression} is false
   */
  public static void checkState(boolean expression, Object errorMessage) {
    if (!expression) {
      throw new IllegalStateException(String.valueOf(errorMessage));
    }
  }

  /**
   * Ensures the truth of an expression involving the state of the calling
   * instance, but not involving any parameters to the calling method.
   *
   * @param expression a boolean expression
   * @param errorMessageTemplate a template for the exception message should the
   *     check fail. The message is formed by replacing each {@code %s}
   *     placeholder in the template with an argument. These are matched by
   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
   *     Unmatched arguments will be appended to the formatted message in square
   *     braces. Unmatched placeholders will be left as-is.
   * @param errorMessageArgs the arguments to be substituted into the message
   *     template. Arguments are converted to strings using
   *     {@link String#valueOf(Object)}.
   * @throws IllegalStateException if {@code expression} is false
   * @throws NullPointerException if the check fails and either {@code
   *     errorMessageTemplate} or {@code errorMessageArgs} is null (don't let
   *     this happen)
   */
  public static void checkState(boolean expression,
      String errorMessageTemplate, Object... errorMessageArgs) {
    if (!expression) {
      throw new IllegalStateException(
          format(errorMessageTemplate, errorMessageArgs));
    }
  }

  /**
   * Ensures that an object reference passed as a parameter to the calling
   * method is not null.
   *
   * @param reference an object reference
   * @return the non-null reference that was validated
   * @throws NullPointerException if {@code reference} is null
   */
  public static <T> T checkNotNull(T reference) {
    if (reference == null) {
      throw new NullPointerException();
    }
    return reference;
  }

  /**
   * Ensures that an object reference passed as a parameter to the calling
   * method is not null.
   *
   * @param reference an object reference
   * @param errorMessage the exception message to use if the check fails; will
   *     be converted to a string using {@link String#valueOf(Object)}
   * @return the non-null reference that was validated
   * @throws NullPointerException if {@code reference} is null
   */
  public static <T> T checkNotNull(T reference, Object errorMessage) {
    if (reference == null) {
      throw new NullPointerException(String.valueOf(errorMessage));
    }
    return reference;
  }

  /**
   * Ensures that an object reference passed as a parameter to the calling
   * method is not null.
   *
   * @param reference an object reference
   * @param errorMessageTemplate a template for the exception message should the
   *     check fail. The message is formed by replacing each {@code %s}
   *     placeholder in the template with an argument. These are matched by
   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
   *     Unmatched arguments will be appended to the formatted message in square
   *     braces. Unmatched placeholders will be left as-is.
   * @param errorMessageArgs the arguments to be substituted into the message
   *     template. Arguments are converted to strings using
   *     {@link String#valueOf(Object)}.
   * @return the non-null reference that was validated
   * @throws NullPointerException if {@code reference} is null
   */
  public static <T> T checkNotNull(T reference, String errorMessageTemplate,
      Object... errorMessageArgs) {
    if (reference == null) {
      // If either of these parameters is null, the right thing happens anyway
      throw new NullPointerException(
          format(errorMessageTemplate, errorMessageArgs));
    }
    return reference;
  }

  /**
   * Ensures that an {@code Iterable} object passed as a parameter to the
   * calling method is not null and contains no null elements.
   *
   * @param iterable the iterable to check the contents of
   * @return the non-null {@code iterable} reference just validated
   * @throws NullPointerException if {@code iterable} is null or contains at
   *     least one null element
   */
  public static <T extends Iterable<?>> T checkContentsNotNull(T iterable) {
    if (containsOrIsNull(iterable)) {
      throw new NullPointerException();
    }
    return iterable;
  }

  /**
   * Ensures that an {@code Iterable} object passed as a parameter to the
   * calling method is not null and contains no null elements.
   *
   * @param iterable the iterable to check the contents of
   * @param errorMessage the exception message to use if the check fails; will
   *     be converted to a string using {@link String#valueOf(Object)}
   * @return the non-null {@code iterable} reference just validated
   * @throws NullPointerException if {@code iterable} is null or contains at
   *     least one null element
   */
  public static <T extends Iterable<?>> T checkContentsNotNull(
      T iterable, Object errorMessage) {
    if (containsOrIsNull(iterable)) {
      throw new NullPointerException(String.valueOf(errorMessage));
    }
    return iterable;
  }

  /**
   * Ensures that an {@code Iterable} object passed as a parameter to the
   * calling method is not null and contains no null elements.
   *
   * @param iterable the iterable to check the contents of
   * @param errorMessageTemplate a template for the exception message should the
   *     check fail. The message is formed by replacing each {@code %s}
   *     placeholder in the template with an argument. These are matched by
   *     position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc.
   *     Unmatched arguments will be appended to the formatted message in square
   *     braces. Unmatched placeholders will be left as-is.
   * @param errorMessageArgs the arguments to be substituted into the message
   *     template. Arguments are converted to strings using
   *     {@link String#valueOf(Object)}.
   * @return the non-null {@code iterable} reference just validated
   * @throws NullPointerException if {@code iterable} is null or contains at
   *     least one null element
   */
  public static <T extends Iterable<?>> T checkContentsNotNull(T iterable,
      String errorMessageTemplate, Object... errorMessageArgs) {
    if (containsOrIsNull(iterable)) {
      throw new NullPointerException(
          format(errorMessageTemplate, errorMessageArgs));
    }
    return iterable;
  }
  
  private static boolean containsOrIsNull(Iterable<?> iterable) {
    if (iterable == null) {
      return true;
    }
    
    if (iterable instanceof Collection) {
      Collection<?> collection = (Collection<?>) iterable;
      try {
        return collection.contains(null);
      } catch (NullPointerException e) {
        // A NPE implies that the collection doesn't contain null.
        return false;
      }
    } else {
      for (Object element : iterable) {
        if (element == null) {
          return true;
        }
      }
      return false;
    }
  }

  /**
   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
   * list or string of size {@code size}. An element index may range from zero,
   * inclusive, to {@code size}, exclusive.
   *
   * @param index a user-supplied index identifying an element of an array, list
   *     or string
   * @param size the size of that array, list or string
   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
   *     less than {@code size}
   * @throws IllegalArgumentException if {@code size} is negative
   */
  public static void checkElementIndex(int index, int size) {
    checkElementIndex(index, size, "index");
  }

  /**
   * Ensures that {@code index} specifies a valid <i>element</i> in an array,
   * list or string of size {@code size}. An element index may range from zero,
   * inclusive, to {@code size}, exclusive.
   *
   * @param index a user-supplied index identifying an element of an array, list
   *     or string
   * @param size the size of that array, list or string
   * @param desc the text to use to describe this index in an error message
   * @throws IndexOutOfBoundsException if {@code index} is negative or is not
   *     less than {@code size}
   * @throws IllegalArgumentException if {@code size} is negative
   */
  public static void checkElementIndex(int index, int size, String desc) {
    checkArgument(size >= 0, "negative size: %s", size);
    if (index < 0) {
      throw new IndexOutOfBoundsException(
          format("%s (%s) must not be negative", desc, index));
    }
    if (index >= size) {
      throw new IndexOutOfBoundsException(
          format("%s (%s) must be less than size (%s)", desc, index, size));
    }
  }

  /**
   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
   * list or string of size {@code size}. A position index may range from zero
   * to {@code size}, inclusive.
   *
   * @param index a user-supplied index identifying a position in an array, list
   *     or string
   * @param size the size of that array, list or string
   * @throws IndexOutOfBoundsException if {@code index} is negative or is
   *     greater than {@code size}
   * @throws IllegalArgumentException if {@code size} is negative
   */
  public static void checkPositionIndex(int index, int size) {
    checkPositionIndex(index, size, "index");
  }

  /**
   * Ensures that {@code index} specifies a valid <i>position</i> in an array,
   * list or string of size {@code size}. A position index may range from zero
   * to {@code size}, inclusive.
   *
   * @param index a user-supplied index identifying a position in an array, list
   *     or string
   * @param size the size of that array, list or string
   * @param desc the text to use to describe this index in an error message
   * @throws IndexOutOfBoundsException if {@code index} is negative or is
   *     greater than {@code size}
   * @throws IllegalArgumentException if {@code size} is negative
   */
  public static void checkPositionIndex(int index, int size, String desc) {
    checkArgument(size >= 0, "negative size: %s", size);
    if (index < 0) {
      throw new IndexOutOfBoundsException(format(
          "%s (%s) must not be negative", desc, index));
    }
    if (index > size) {
      throw new IndexOutOfBoundsException(format(
          "%s (%s) must not be greater than size (%s)", desc, index, size));
    }
  }

  /**
   * Ensures that {@code start} and {@code end} specify a valid <i>positions</i>
   * in an array, list or string of size {@code size}, and are in order. A
   * position index may range from zero to {@code size}, inclusive.
   *
   * @param start a user-supplied index identifying a starting position in an
   *     array, list or string
   * @param end a user-supplied index identifying a ending position in an array,
   *     list or string
   * @param size the size of that array, list or string
   * @throws IndexOutOfBoundsException if either index is negative or is
   *     greater than {@code size}, or if {@code end} is less than {@code start}
   * @throws IllegalArgumentException if {@code size} is negative
   */
  public static void checkPositionIndexes(int start, int end, int size) {
    checkPositionIndex(start, size, "start index");
    checkPositionIndex(end, size, "end index");
    if (end < start) {
      throw new IndexOutOfBoundsException(format(
          "end index (%s) must not be less than start index (%s)", end, start));
    }
  }

  /**
   * Substitutes each {@code %s} in {@code template} with an argument. These
   * are matched by position - the first {@code %s} gets {@code args[0]}, etc.
   * If there are more arguments than placeholders, the unmatched arguments will
   * be appended to the end of the formatted message in square braces.
   *
   * @param template a non-null string containing 0 or more {@code %s}
   *     placeholders.
   * @param args the arguments to be substituted into the message
   *     template. Arguments are converted to strings using
   *     {@link String#valueOf(Object)}. Arguments can be null.
   */
  // VisibleForTesting
  static String format(String template, Object... args) {
    // start substituting the arguments into the '%s' placeholders
    StringBuilder builder = new StringBuilder(
        template.length() + 16 * args.length);
    int templateStart = 0;
    int i = 0;
    while (i < args.length) {
      int placeholderStart = template.indexOf("%s", templateStart);
      if (placeholderStart == -1) {
        break;
      }
      builder.append(template.substring(templateStart, placeholderStart));
      builder.append(args[i++]);
      templateStart = placeholderStart + 2;
    }
    builder.append(template.substring(templateStart));

    // if we run out of placeholders, append the extra args in square braces
    if (i < args.length) {
      builder.append(" [");
      builder.append(args[i++]);
      while (i < args.length) {
        builder.append(", ");
        builder.append(args[i++]);
      }
      builder.append("]");
    }

    return builder.toString();
  }
}
