// Copyright 2018 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.devtools.build.lib.exec;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertThrows;

import com.google.devtools.build.lib.actions.ActionContext;
import com.google.devtools.build.lib.util.AbruptExitException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link ModuleActionContextRegistry}. */
@RunWith(JUnit4.class)
public class ModuleActionContextRegistryTest {

  @Test
  public void testRegistration() throws Exception {
    AC2 context = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder().register(IT1.class, context).build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(context);
  }

  @Test
  public void testDoubleRegistration() throws Exception {
    AC2 context = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, context)
            .register(IT1.class, context)
            .build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(context);
  }

  @Test
  public void testLastRegisteredHasPriority() throws Exception {
    AC2 context1 = new AC2();
    AC2 context2 = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, context1)
            .register(IT1.class, context2)
            .build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(context2);
  }

  @Test
  public void testSelfIdentifyingType() throws Exception {
    AC1 context = new AC1();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder().register(AC1.class, context).build();
    assertThat(contextRegistry.getContext(AC1.class)).isEqualTo(context);
  }

  @Test
  public void testIdentifierFilter() throws Exception {
    AC2 general = new AC2();
    AC2 specific = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, general)
            .register(IT1.class, specific, "specific", "foo")
            .register(IT1.class, general)
            .restrictTo(IT1.class, "specific")
            .build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(specific);
  }

  @Test
  public void testLastRegisteredHasPriorityWithIdentifier() throws Exception {
    AC2 context1 = new AC2();
    AC2 context2 = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, context1, "foo")
            .register(IT1.class, context2, "foo")
            .restrictTo(IT1.class, "foo")
            .build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(context2);
  }

  @Test
  public void testUsedNotification() throws Exception {
    RecordingContext context = new RecordingContext();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(RecordingContext.class, context)
            .register(RecordingContext.class, context)
            .build();

    contextRegistry.notifyUsed();

    assertThat(context.usedCalls).isEqualTo(1);
  }

  @Test
  public void testEmptyRestriction() throws Exception {
    AC2 general = new AC2();
    AC2 specific = new AC2();
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, general)
            .register(IT1.class, specific, "specific", "foo")
            .register(IT1.class, general)
            .restrictTo(IT1.class, "specific")
            .restrictTo(IT1.class, "")
            .build();
    assertThat(contextRegistry.getContext(IT1.class)).isEqualTo(general);
  }

  @Test
  public void testNoMatch() throws Exception {
    ModuleActionContextRegistry contextRegistry =
        ModuleActionContextRegistry.builder().register(AC1.class, new AC1()).build();

    assertThat(contextRegistry.getContext(IT1.class)).isNull();
  }

  @Test
  public void testUnfulfilledRestriction() {
    AC2 context1 = new AC2();
    AC2 context2 = new AC2();
    ModuleActionContextRegistry.Builder builder =
        ModuleActionContextRegistry.builder()
            .register(IT1.class, context1, "foo")
            .register(IT1.class, context2, "baz", "boz")
            .restrictTo(IT1.class, "bar");

    AbruptExitException exception = assertThrows(AbruptExitException.class, builder::build);
    assertThat(exception).hasMessageThat().containsMatch("IT1.*bar.*[foo, baz, boz]");
  }

  private static class AC1 implements ActionContext {}

  private interface IT1 extends ActionContext {}

  private static class AC2 implements IT1 {}

  private static class RecordingContext implements ActionContext {
    private int usedCalls = 0;

    @Override
    public void usedContext(ActionContext.ActionContextRegistry actionContextRegistry) {
      usedCalls++;
    }
  }
}
