/*
 * 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.jclouds.util;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.jclouds.util.Throwables2.getFirstThrowableOfType;

import java.util.Date;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.annotation.Resource;

import org.jclouds.logging.Logger;

import com.google.common.base.Predicate;

public class Predicates2 {
   /** Returns a predicate that evaluates to true if the String being tested starts with a prefix. */
   public static Predicate<String> startsWith(final String prefix) {
      return new Predicate<String>() {
         @Override
         public boolean apply(final String input) {
             return input.startsWith(prefix);
         }

         @Override
         public String toString() {
            return "startsWith(" + prefix + ")";
         }
      };
   }

   /**
    * Retries a predicate until it is met, a timeout occurs, or an exception occurs.
    */
   public static <T> Predicate<T> retry(Predicate<T> findOrBreak, long timeout, long period, long maxPeriod,
         TimeUnit unit) {
      return new RetryablePredicate<T>(findOrBreak, timeout, period, maxPeriod, unit);
   }

   /**
    * like {@link #retry(Predicate, long, long, long, TimeUnit)} where {@code maxPeriod} is 10x {@code period}
    */
   public static <T> Predicate<T> retry(Predicate<T> findOrBreak, long timeout, long period, TimeUnit unit) {
      return retry(findOrBreak, timeout, period, period * 10L, unit);
   }

   /**
    * like {@link #retry(Predicate, long, long, long, TimeUnit)} where {@code unit} is in milliseconds
    */
   public static <T> Predicate<T> retry(Predicate<T> findOrBreak, long timeout, long period, long maxPeriod) {
      return retry(findOrBreak, timeout, period, maxPeriod, MILLISECONDS);
   }

   /**
    * @see org.jclouds.compute.config.ComputeServiceProperties#POLL_INITIAL_PERIOD
    */
   public static final long DEFAULT_PERIOD = 50L;
   /**
    * @see org.jclouds.compute.config.ComputeServiceProperties#POLL_MAX_PERIOD
    */
   public static final long DEFAULT_MAX_PERIOD = 1000L;

   /**
    * like {@link #retry(Predicate, long, long, long, TimeUnit)} where {@code unit} is in milliseconds, {@code period}
    * is 50ms, and {@code maxPeriod} 1s.
    */
   public static <T> Predicate<T> retry(Predicate<T> findOrBreak, long timeout) {
      return retry(findOrBreak, timeout, DEFAULT_PERIOD, DEFAULT_MAX_PERIOD, MILLISECONDS);
   }

   private static class RetryablePredicate<T> implements Predicate<T> {
      private final long timeout;
      private final long period;
      private final long maxPeriod;
      private final Predicate<T> findOrBreak;

      @Resource
      protected Logger logger = Logger.NULL;

      protected RetryablePredicate(Predicate<T> findOrBreak, long timeout, long period, long maxPeriod, TimeUnit unit) {
         this.findOrBreak = findOrBreak;
         this.timeout = unit.toMillis(timeout);
         this.period = unit.toMillis(period);
         this.maxPeriod = unit.toMillis(maxPeriod);
      }
      
      @Override
      public boolean apply(T input) {
         // Ensure that try one last time at the end (e.g. if timeout is 30 secs and last sleep
         // takes us up to the 30 secs mark, then test again rather than returning immediately 
         // after the sleep!).
         // Always try at least once, even if timeout is 0 or negative.
         // A timeout of 0 means 0 millis.
         try {
            long i = 1L;
            long now = System.currentTimeMillis();
            long end = now + timeout;
            while (now < end) {
               if (findOrBreak.apply(input)) {
                  return true;
               }
               long sleepTime = nextMaxInterval(i++, end);
               if (sleepTime > 0) Thread.sleep(sleepTime);
               now = System.currentTimeMillis();
            }

            return findOrBreak.apply(input);

         } catch (InterruptedException e) {
            logger.warn(e, "predicate %s on %s interrupted, returning false", input, findOrBreak);
            Thread.currentThread().interrupt();
            return false;
         } catch (RuntimeException e) {
            if (getFirstThrowableOfType(e, ExecutionException.class) != null) {
               logger.warn(e, "predicate %s on %s errored [%s], returning false", input, findOrBreak, e.getMessage());
               return false;
            } else if (getFirstThrowableOfType(e, IllegalStateException.class) != null) {
               logger.warn(e, "predicate %s on %s illegal state [%s], returning false", input, findOrBreak, e.getMessage());
               return false;
            } else if (getFirstThrowableOfType(e, CancellationException.class) != null) {
               logger.warn(e, "predicate %s on %s cancelled [%s], returning false", input, findOrBreak, e.getMessage());
               return false;
            } else if (getFirstThrowableOfType(e, TimeoutException.class) != null) {
               logger.warn(e, "predicate %s on %s timed out [%s], returning false", input, findOrBreak, e.getMessage());
               return false;
            } else
               throw e;
         }
      }

      /**
       * @deprecated since 1.9.0; use {@link #nextMaxInterval(long, long)}
       */
      @Deprecated
      protected long nextMaxInterval(long attempt, Date end) {
         return nextMaxInterval(attempt, end.getTime());
      }

      /**
       * Calculates the time interval to a retry attempt.<p>
       * The interval increases exponentially with each attempt, at a rate of nextInterval *= 1.5
       * (where 1.5 is the backoff factor), to the maximum interval or specified timeout.
       * 
       * @param attempt number of this attempt (starting at 1 for the first retry)
       * @param endTime timeout
       * @return time in milliseconds from now until the next attempt, or if negative, time lapsed
       * since the specified timeout
       */
      protected long nextMaxInterval(long attempt, long endTime) {
         long interval = (long) (period * Math.pow(1.5, attempt - 1));
         interval = interval > maxPeriod ? maxPeriod : interval;
         long max = endTime - System.currentTimeMillis();
         return (interval > max) ? max : interval;
      }

      /**
       * @deprecated since 1.9.0; use {@link #nextMaxInterval(long, long)}
       */
      @Deprecated
      protected boolean before(Date end) {
         return new Date().compareTo(end) < 0;
      }

      /**
       * @deprecated since 1.9.0; use {@link #nextMaxInterval(long, long)}
       */
      @Deprecated
      protected boolean atOrAfter(Date end) {
         return new Date().compareTo(end) >= 0;
      }
   }   
}
