/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.idea.blaze.base.scope;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.idea.blaze.base.BlazeTestCase;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;

import java.util.List;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

/**
 * Tests for {@link BlazeContext}.
 */
public class BlazeContextTest extends BlazeTestCase {

  @Test
  public void testScopeBeginsWhenPushedToContext() {
    BlazeContext context = new BlazeContext();
    final BlazeScope scope = mock(BlazeScope.class);
    context.push(scope);
    verify(scope).onScopeBegin(context);
  }

  @Test
  public void testScopeEndsWhenContextEnds() {
    BlazeContext context = new BlazeContext();
    final BlazeScope scope = mock(BlazeScope.class);
    context.push(scope);
    context.endScope();
    verify(scope).onScopeEnd(context);
  }

  @Test
  public void testEndingTwiceHasNoEffect() {
    BlazeContext context = new BlazeContext();
    final BlazeScope scope = mock(BlazeScope.class);
    context.push(scope);
    context.endScope();
    context.endScope();
    verify(scope).onScopeEnd(context);
  }

  @Test
  public void testEndingScopeNormallyDoesntEndParent() {
    BlazeContext parentContext = new BlazeContext();
    BlazeContext childContext = new BlazeContext(parentContext);
    childContext.endScope();
    assertTrue(childContext.isEnding());
    assertFalse(parentContext.isEnding());
  }

  @Test
  public void testCancellingScopeCancelsParent() {
    BlazeContext parentContext = new BlazeContext();
    BlazeContext childContext = new BlazeContext(parentContext);
    childContext.setCancelled();
    assertTrue(childContext.isCancelled());
    assertTrue(parentContext.isCancelled());
  }

  /**
   * A simple scope that records its start and end by ID.
   */
  static class RecordScope implements BlazeScope {
    private final int id;
    private final List<String> record;

    public RecordScope(int id, List<String> record) {
      this.id = id;
      this.record = record;
    }

    @Override
    public void onScopeBegin(@NotNull BlazeContext context) {
      record.add("begin" + id);
    }

    @Override
    public void onScopeEnd(@NotNull BlazeContext context) {
      record.add("end" + id);
    }
  }

  @Test
  public void testScopesBeginAndEndInStackOrder() {
    List<String> record = Lists.newArrayList();
    BlazeContext context = new BlazeContext();
    context
      .push(new RecordScope(1, record))
      .push(new RecordScope(2, record))
      .push(new RecordScope(3, record));
    context.endScope();
    assertThat(record)
      .isEqualTo(ImmutableList.of("begin1", "begin2", "begin3", "end3", "end2", "end1"));
  }

  @Test
  public void testParentFoundInStackOrder() {
    BlazeContext context = new BlazeContext();
    BlazeScope scope1 = mock(BlazeScope.class);
    BlazeScope scope2 = mock(BlazeScope.class);
    BlazeScope scope3 = mock(BlazeScope.class);
    context
      .push(scope1)
      .push(scope2)
      .push(scope3);
    assertThat(context.getParentScope(scope3)).isEqualTo(scope2);
    assertThat(context.getParentScope(scope2)).isEqualTo(scope1);
    assertThat(context.getParentScope(scope1)).isNull();
  }

  @Test
  public void testParentFoundInStackOrderAcrossContexts() {
    BlazeContext parentContext = new BlazeContext();
    BlazeContext childContext = new BlazeContext(parentContext);
    BlazeScope scope1 = mock(BlazeScope.class);
    BlazeScope scope2 = mock(BlazeScope.class);
    BlazeScope scope3 = mock(BlazeScope.class);
    parentContext
      .push(scope1)
      .push(scope2);
    childContext
      .push(scope3);
    assertThat(childContext.getParentScope(scope3)).isEqualTo(scope2);
  }

  static class TestOutput1 implements Output {
  }

  static class TestOutput2 implements Output {
  }

  static class TestOutputSink<T extends Output> implements OutputSink<T> {
    public boolean gotOutput;

    @Override
    public Propagation onOutput(@NotNull T output) {
      gotOutput = true;
      return Propagation.Continue;
    }
  }

  static class TestOutputSink1 extends TestOutputSink<TestOutput1> {
  }

  static class TestOutputSink2 extends TestOutputSink<TestOutput2> {
  }

  @Test
  public void testOutputGoesToRegisteredSink() {
    BlazeContext context = new BlazeContext();
    TestOutputSink1 sink = new TestOutputSink1();
    context.addOutputSink(TestOutput1.class, sink);

    assertFalse(sink.gotOutput);
    context.output(new TestOutput1());
    assertTrue(sink.gotOutput);
  }

  @Test
  public void testOutputDoesntGoToWrongSink() {
    BlazeContext context = new BlazeContext();
    TestOutputSink2 sink = new TestOutputSink2();
    context.addOutputSink(TestOutput2.class, sink);

    assertFalse(sink.gotOutput);
    context.output(new TestOutput1());
    assertFalse(sink.gotOutput);
  }

  @Test
  public void testOutputGoesToParentContexts() {
    BlazeContext parentContext = new BlazeContext();
    BlazeContext childContext = new BlazeContext(parentContext);
    TestOutputSink1 sink = new TestOutputSink1();
    parentContext.addOutputSink(TestOutput1.class, sink);

    assertFalse(sink.gotOutput);
    childContext.output(new TestOutput1());
    assertTrue(sink.gotOutput);
  }

  @Test
  public void testHoldingPreventsEndingContext() {
    BlazeContext context = new BlazeContext();
    context.hold();
    context.endScope();
    assertFalse(context.isEnding());
    context.release();
    assertTrue(context.isEnding());
  }

  private static class StringScope implements BlazeScope {

    public final String str;

    public StringScope(String s) {
      this.str = s;
    }

    @Override
    public void onScopeBegin(@NotNull BlazeContext context) {

    }

    @Override
    public void onScopeEnd(@NotNull BlazeContext context) {

    }
  }

  private static class CollectorScope implements BlazeScope {

    public final List<String> output;

    public CollectorScope(List<String> output) {
      this.output = output;
    }

    @Override
    public void onScopeBegin(@NotNull BlazeContext context) {

    }

    @Override
    public void onScopeEnd(@NotNull BlazeContext context) {
      List<StringScope> scopes = context.getScopes(StringScope.class, this);
      for (StringScope scope : scopes) {
        output.add(scope.str);
      }
    }
  }

  @Test
  public void testGetScopesOnlyReturnsScopesLowerOnTheStack() {
    List<String> output1 = Lists.newArrayList();
    List<String> output2 = Lists.newArrayList();
    List<String> output3 = Lists.newArrayList();

    BlazeContext context = new BlazeContext();
    context.push(new StringScope("a"));
    context.push(new StringScope("b"));
    CollectorScope scope = new CollectorScope(output1);
    context.push(scope);
    context.push(new StringScope("c"));
    context.push(new CollectorScope(output2));
    context.push(new StringScope("d"));
    context.push(new StringScope("e"));
    context.push(new CollectorScope(output3));
    context.endScope();

    assertThat(output1).isEqualTo(ImmutableList.of("b", "a"));
    assertThat(output2).isEqualTo(ImmutableList.of("c", "b", "a"));
    assertThat(output3).isEqualTo(ImmutableList.of("e", "d", "c", "b", "a"));
  }

  @Test
  public void testGetScopesOnlyReturnsScopesLowerOnTheStackForMultipleContexts() {
    List<String> output1 = Lists.newArrayList();
    List<String> output2 = Lists.newArrayList();
    List<String> output3 = Lists.newArrayList();

    BlazeContext context1 = new BlazeContext();
    context1.push(new StringScope("a"));
    context1.push(new StringScope("b"));
    CollectorScope scope = new CollectorScope(output1);
    context1.push(scope);

    BlazeContext context2 = new BlazeContext(context1);
    context2.push(new StringScope("c"));
    context2.push(new CollectorScope(output2));
    context2.push(new StringScope("d"));
    context2.push(new StringScope("e"));

    BlazeContext context3 = new BlazeContext(context2);
    context3.push(new CollectorScope(output3));
    context3.endScope();
    context2.endScope();
    context1.endScope();

    assertThat(output1).isEqualTo(ImmutableList.of("b", "a"));
    assertThat(output2).isEqualTo(ImmutableList.of("c", "b", "a"));
    assertThat(output3).isEqualTo(ImmutableList.of("e", "d", "c", "b", "a"));
  }

  @Test
  public void testGetScopesOnlyReturnsScopesIfStartingScopeInContext() {
    List<String> output1 = Lists.newArrayList();

    BlazeContext context1 = new BlazeContext();
    context1.push(new StringScope("a"));
    context1.push(new StringScope("b"));
    CollectorScope scope = new CollectorScope(output1);
    context1.push(scope);

    BlazeContext context2 = new BlazeContext(context1);
    context2.push(new StringScope("c"));

    List<StringScope> scopes = context2.getScopes(StringScope.class, scope);
    assertThat(scopes).isEqualTo(ImmutableList.of());
  }

  @Test
  public void testGetScopesIncludesStartingScope() {
    BlazeContext context1 = new BlazeContext();
    StringScope a = new StringScope("a");
    context1.push(a);
    StringScope b = new StringScope("b");
    context1.push(b);

    List<StringScope> scopes = context1.getScopes(StringScope.class, b);
    assertThat(scopes).isEqualTo(ImmutableList.of(b, a));
  }

  @Test
  public void testGetScopesIndexIsNoninclusive() {
    BlazeContext context1 = new BlazeContext();
    StringScope scopeA = new StringScope("a");
    context1.push(scopeA);
    StringScope scopeB = new StringScope("b");
    context1.push(scopeB);

    List<StringScope> scopes = Lists.newArrayList();
    context1.getScopes(scopes, StringScope.class, 1);
    assertThat(scopes).isEqualTo(ImmutableList.of(scopeA));
  }

  @Test
  public void testGetScopesWithoutStartScopeGetsAll() {
    BlazeContext context1 = new BlazeContext();
    StringScope a = new StringScope("a");
    context1.push(a);
    StringScope b = new StringScope("b");
    context1.push(b);

    List<StringScope> scopes = context1.getScopes(StringScope.class);
    assertThat(scopes).isEqualTo(ImmutableList.of(b, a));
  }

  static class NonPropagatingOutputSink implements OutputSink<TestOutput1> {
    boolean gotOutput;

    @Override
    public Propagation onOutput(@NotNull TestOutput1 output) {
      this.gotOutput = true;
      return Propagation.Stop;
    }
  }

  @Test
  public void testOutputIsTerminatedByFirstSink() {
    NonPropagatingOutputSink sink1 = new NonPropagatingOutputSink();
    NonPropagatingOutputSink sink2 = new NonPropagatingOutputSink();
    NonPropagatingOutputSink sink3 = new NonPropagatingOutputSink();

    BlazeContext context1 = new BlazeContext();
    context1.addOutputSink(TestOutput1.class, sink1);

    BlazeContext context2 = new BlazeContext(context1);
    context2.addOutputSink(TestOutput1.class, sink2);
    context2.addOutputSink(TestOutput1.class, sink3);

    context2.output(new TestOutput1());

    assertThat(sink1.gotOutput).isFalse();
    assertThat(sink2.gotOutput).isFalse();
    assertThat(sink3.gotOutput).isTrue();
  }
}
