/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.openapi.util;

import com.intellij.reference.SoftReference;
import com.intellij.util.ArrayUtilRt;
import org.jetbrains.annotations.NotNull;

import java.util.HashMap;

/**
 * @author max
 */
public class Conditions {
  private Conditions() {}

  @NotNull
  public static <T> Condition<T> alwaysTrue() {
    return (Condition<T>)TRUE;
  }
  @NotNull
  public static <T> Condition<T> alwaysFalse() {
    return (Condition<T>)FALSE;
  }

  public static <T> Condition<T> instanceOf(final Class<?> clazz) {
    return new Condition<T>() {
      @Override
      public boolean value(T t) {
        return clazz.isInstance(t);
      }
    };
  }

  public static <T> Condition<T> is(final T option) {
    return new Condition<T>() {
      @Override
      public boolean value(T t) {
        return Comparing.equal(t, option);
      }
    };
  }

  public static <T> Condition<T> oneOf(final T... options) {
    return new Condition<T>() {
      @Override
      public boolean value(T t) {
        return ArrayUtilRt.find(options, t) >= 0;
      }
    };
  }

  public static <T> Condition<T> not(Condition<T> c) {
    return new Not<T>(c);
  }
  public static <T> Condition<T> and(Condition<T> c1, Condition<T> c2) {
    return new And<T>(c1, c2);
  }
  public static <T> Condition<T> or(Condition<T> c1, Condition<T> c2) {
    return new Or<T>(c1, c2);
  }
  public static <T> Condition<T> cached(Condition<T> c) {
    return new SoftRefCache<T>(c);
  }

  private static class Not<T> implements Condition<T> {
    private final Condition<T> myCondition;

    public Not(Condition<T> condition) {
      myCondition = condition;
    }

    @Override
    public boolean value(T value) {
      return !myCondition.value(value);
    }
  }
  private static class And<T> implements Condition<T>  {
    private final Condition<T> t1;
    private final Condition<T> t2;

    public And(final Condition<T> t1, final Condition<T> t2) {
      this.t1 = t1;
      this.t2 = t2;
    }

    @Override
    public boolean value(final T object) {
      return t1.value(object) && t2.value(object);
    }
  }
  private static class Or<T> implements Condition<T>  {
    private final Condition<T> t1;
    private final Condition<T> t2;

    public Or(final Condition<T> t1, final Condition<T> t2) {
      this.t1 = t1;
      this.t2 = t2;
    }

    @Override
    public boolean value(final T object) {
      return t1.value(object) || t2.value(object);
    }
  }

  public static Condition<Object> TRUE = new Condition<Object>() {
    @Override
    public boolean value(final Object object) {
      return true;
    }
  };
  public static Condition<Object> FALSE = new Condition<Object>() {
    @Override
    public boolean value(final Object object) {
      return false;
    }
  };

  private static class SoftRefCache<T> implements Condition<T> {
    private final HashMap<Integer, Pair<SoftReference<T>, Boolean>> myCache = new HashMap<Integer, Pair<SoftReference<T>, Boolean>>();
    private final Condition<T> myCondition;

    public SoftRefCache(Condition<T> condition) {
      myCondition = condition;
    }

    @Override
    public final boolean value(T object) {
      final int key = object.hashCode();
      final Pair<SoftReference<T>, Boolean> entry = myCache.get(key);
      if (entry == null || entry.first.get() != object) {
        boolean value = myCondition.value(object);
        myCache.put(key, Pair.create(new SoftReference<T>(object), value));
        return value;
      }
      else {
        return entry.second;
      }
    }
  }
}
