/*
 * Copyright 2000-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 com.intellij.execution.filters;

import com.intellij.mock.MockDumbService;
import com.intellij.testFramework.ProjectRule;
import org.jetbrains.annotations.Nullable;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.util.List;

public class CompositeFilterTest {
  @Rule
  public final ProjectRule appRule = new ProjectRule();

  protected CompositeFilter myCompositeFilter;

  @Before
  public void setUp() throws Exception {
    myCompositeFilter = new CompositeFilter(new MockDumbService(null));
    myCompositeFilter.setForceUseAllFilters(false);
  }

  @Test
  public void testApplyNextFilter() throws Exception {
    Assert.assertNull(applyFilter());

    myCompositeFilter.addFilter(returnNullFilter());
    Assert.assertNull(applyFilter());

    myCompositeFilter.addFilter(returnContinuingResultFilter());
    notNullResultOfSize(applyFilter(), 1);

    myCompositeFilter.addFilter(returnNullFilter());
    myCompositeFilter.addFilter(returnContinuingResultFilter());
    notNullResultOfSize(applyFilter(), 2);

    myCompositeFilter.addFilter(returnNullFilter());
    notNullResultOfSize(applyFilter(), 2);

    myCompositeFilter.addFilter(returnResultFilter());
    notNullResultOfSize(applyFilter(), 3);

    myCompositeFilter.addFilter(returnResultFilter());
    notNullResultOfSize(applyFilter(), 3);

    myCompositeFilter.setForceUseAllFilters(true);
    notNullResultOfSize(applyFilter(), 4);

  }

  @Test
  public void testApplyBadFilter() throws Exception {
    myCompositeFilter.addFilter(throwSOEFilter());
    try {
      Assert.assertNull(applyFilter());
      Assert.fail("Exception expected");
    }
    catch (Exception e) {
      Assert.assertTrue(e.getMessage().contains("Error while applying com.intellij.execution.filters.CompositeFilterTest$"));
    }
  }

  private Filter.Result applyFilter() {
    return myCompositeFilter.applyFilter("foo\n", 10);
  }

  private static void notNullResultOfSize(Filter.Result object, int expected) {
    Assert.assertNotNull(object);
    List<Filter.ResultItem> resultItems = object.getResultItems();
    Assert.assertEquals(expected, resultItems.size());

    for (Filter.ResultItem resultItem : resultItems) {
      Assert.assertNotNull(resultItem);
    }
  }

  private static Filter throwSOEFilter() {
    //noinspection InfiniteRecursion
    return new Filter() {
      @Nullable
      @Override
      public Result applyFilter(String line, int entireLength) {
        return applyFilter(line, entireLength);
      }
    };
  }

  private static Filter returnNullFilter() {
    return new Filter() {
      @Nullable
      @Override
      public Result applyFilter(String line, int entireLength) {
        return null;
      }
    };
  }

  private static Filter returnResultFilter() {
    return new Filter() {
      @Nullable
      @Override
      public Result applyFilter(String line, int entireLength) {
        return createResult();
      }
    };
  }

  private static Filter returnContinuingResultFilter() {
    return new Filter() {
      @Nullable
      @Override
      public Result applyFilter(String line, int entireLength) {
        Result result = createResult();
        result.setNextAction(NextAction.CONTINUE_FILTERING);
        return result;
      }
    };
  }

  private static Filter.Result createResult() {
    return new Filter.Result(1, 1, null, null);
  }
}
@@ -681,55 +681,8 @@
 ce;%0A
-import com.intellij.testFramework.ProjectRule;%0A
 impo
@@ -716,24 +716,24 @@
 s.Nullable;%0A
+
 import org.j
@@ -774,31 +774,8 @@
 re;%0A
-import org.junit.Rule;%0A
 impo
@@ -818,16 +818,16 @@
 .List;%0A%0A
+
 public c
@@ -856,72 +856,8 @@
 st %7B
-%0A  @Rule%0A  public final ProjectRule appRule = new ProjectRule();
 %0A%0A  

make CompositeFilterTest light again, now that it passes (IDEA-CR-20284)