/*
 * Copyright 2012-2017 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 jetbrains.jetpad.base;

import jetbrains.jetpad.base.function.Consumer;
import jetbrains.jetpad.base.function.Predicate;

/**
 * @deprecated Use {@link AsyncMatchers} instead
 */
@Deprecated
public final class Asserts {
  public static <T> void assertSuccess(Async<T> async) {
    assertSuccess(new Predicate<T>() {
      @Override
      public boolean test(T value) {
        return true;
      }
    }, async);
  }

  public static <T> void assertSuccessValue(T expected, Async<T> async) {
    T value = getResultValue(async);
    if (value == null) {
      if (expected != null) {
        throw new AssertionError("Expected: " + expected + ", but got: " + value);
      }
    } else if (!value.equals(expected)) {
      throw new AssertionError("Expected: " + expected + ", but got: " + value);
    }
  }

  public static <T> void assertSuccess(Predicate<T> assertion, Async<T> async) {
    T value = getResultValue(async);
    if (!assertion.test(value)) {
      throw new AssertionError("success value failed assertion: " + value);
    }
  }

  public static void assertFailure(Async<?> async) {
    assertFailure(Throwable.class, async);
  }

  public static void assertFailure(Class<? extends Throwable> expected, Async<?> async) {
    AsyncResult<?> result = getResult(async);
    if (result.state != AsyncState.FAILED) {
      throw new AssertionError("Async expected to fail async=" + async + ", value=" + result.value
          + ", state=" + result.state);
    }
    Throwable t = result.error;
    if (!expected.isAssignableFrom(t.getClass())) {
      throw new AssertionError("Async failed with unexpected exception expected=" + expected + ", actual=" + t);
    }
  }

  public static <T> T getResultValue(Async<T> async) {
    AsyncResult<T> result = getResult(async);
    if (result.state != AsyncState.SUCCEEDED) {
      throw new AssertionError("Async expected to succeed async=" + async + ", failure=" + result.error
          + ", state=" + result.state);
    }
    return result.value;
  }

  private static <T> AsyncResult<T> getResult(Async<T> async) {
    final Value<AsyncResult<T>> resultValue = new Value<>(new AsyncResult<T>(AsyncState.UNFINISHED, null, null));
    async.onResult(new Consumer<T>() {
      @Override
      public void accept(T value) {
        resultValue.set(new AsyncResult<>(AsyncState.SUCCEEDED, value, null));
      }
    }, new Consumer<Throwable>() {
      @Override
      public void accept(Throwable throwable) {
        resultValue.set(new AsyncResult<T>(AsyncState.FAILED, null, throwable));
      }
    });
    return resultValue.get();
  }

  private Asserts() { }

  private static class AsyncResult<T> {
    private final AsyncState state;
    private final T value;
    private final Throwable error;

    private AsyncResult(AsyncState state, T value, Throwable error) {
      this.state = state;
      this.value = value;
      this.error = error;
    }
  }

  private enum AsyncState {
    UNFINISHED,
    SUCCEEDED,
    FAILED
  }
}
@@ -678,57 +678,8 @@
 mer;
-%0Aimport jetbrains.jetpad.base.function.Predicate;
 %0A%0A/*
@@ -777,205 +777,8 @@
 ts %7B
-%0A  public static %3CT%3E void assertSuccess(Async%3CT%3E async) %7B%0A    assertSuccess(new Predicate%3CT%3E() %7B%0A      @Override%0A      public boolean test(T value) %7B%0A        return true;%0A      %7D%0A    %7D, async);%0A  %7D
 %0A%0A  
@@ -1147,32 +1147,32 @@
 ot: %22 + value);%0A
+
     %7D%0A  %7D%0A%0A  pub
@@ -1170,348 +1170,8 @@
  %7D%0A%0A
-  public static %3CT%3E void assertSuccess(Predicate%3CT%3E assertion, Async%3CT%3E async) %7B%0A    T value = getResultValue(async);%0A    if (!assertion.test(value)) %7B%0A      throw new AssertionError(%22success value failed assertion: %22 + value);%0A    %7D%0A  %7D%0A%0A  public static void assertFailure(Async%3C?%3E async) %7B%0A    assertFailure(Throwable.class, async);%0A  %7D%0A%0A
   pu
@@ -2637,16 +2637,18 @@
 erts() %7B
+%0A 
  %7D%0A%0A  pr
@@ -3016,8 +3016,9 @@
 ED%0A  %7D%0A%7D
+%0A

remove unused deprecated methods (assertSuccess, assertFailure in Asserts)