// 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.devtools.build.lib.syntax;

import static com.google.common.truth.Truth.assertThat;

import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import java.lang.reflect.Method;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 *  Test Skylark interface annotations and utilities.
 */
@RunWith(JUnit4.class)
public class SkylarkInterfaceUtilsTest {

  /** MockClassA */
  @SkylarkModule(name = "MockClassA", doc = "MockClassA")
  public static class MockClassA {
    @SkylarkCallable(doc = "MockClassA#foo")
    public void foo() {}
    @SkylarkCallable(doc = "MockClassA#bar")
    public void bar() {}
    public void baz() {}
  }

  /** MockInterfaceB1 */
  @SkylarkModule(name = "MockInterfaceB1", doc = "MockInterfaceB1")
  public static interface MockInterfaceB1 {
    @SkylarkCallable(doc = "MockInterfaceB1#foo")
    void foo();
    @SkylarkCallable(doc = "MockInterfaceB1#bar")
    void bar();
    @SkylarkCallable(doc = "MockInterfaceB1#baz")
    void baz();
  }

  /** MockInterfaceB2 */
  @SkylarkModule(name = "MockInterfaceB2", doc = "MockInterfaceB2")
  public static interface MockInterfaceB2 {
    @SkylarkCallable(doc = "MockInterfaceB2#baz")
    void baz();
    @SkylarkCallable(doc = "MockInterfaceB2#qux")
    void qux();
  }

  /** MockClassC */
  @SkylarkModule(name = "MockClassC", doc = "MockClassC")
  public static class MockClassC extends MockClassA implements MockInterfaceB1, MockInterfaceB2 {
    @Override
    @SkylarkCallable(doc = "MockClassC#foo")
    public void foo() {}
    @Override
    public void bar() {}
    @Override
    public void baz() {}
    @Override
    public void qux() {}
  }

  /** MockClassD */
  public static class MockClassD extends MockClassC {
    @Override
    @SkylarkCallable(doc = "MockClassD#foo")
    public void foo() {}
  }

  /** MockClassZ */
  public static class MockClassZ {
  }

  // The tests for getSkylarkModule() double as tests for getParentWithSkylarkModule(),
  // since they share an implementation.

  @Test
  public void testGetSkylarkModuleBasic() throws Exception {
    // Normal case.
    SkylarkModule ann = SkylarkInterfaceUtils.getSkylarkModule(MockClassA.class);
    Class<?> cls = SkylarkInterfaceUtils.getParentWithSkylarkModule(MockClassA.class);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA");
    assertThat(cls).isNotNull();
    assertThat(cls).isEqualTo(MockClassA.class);
  }

  @Test
  public void testGetSkylarkModuleSubclass() throws Exception {
    // Subclass's annotation is used.
    SkylarkModule ann = SkylarkInterfaceUtils.getSkylarkModule(MockClassC.class);
    Class<?> cls = SkylarkInterfaceUtils.getParentWithSkylarkModule(MockClassC.class);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassC");
    assertThat(cls).isNotNull();
    assertThat(cls).isEqualTo(MockClassC.class);
  }

  @Test
  public void testGetSkylarkModuleSubclassNoSubannotation() throws Exception {
    // Falls back on superclass's annotation.
    SkylarkModule ann = SkylarkInterfaceUtils.getSkylarkModule(MockClassD.class);
    Class<?> cls = SkylarkInterfaceUtils.getParentWithSkylarkModule(MockClassD.class);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassC");
    assertThat(cls).isNotNull();
    assertThat(cls).isEqualTo(MockClassC.class);
  }

  @Test
  public void testGetSkylarkModuleNotFound() throws Exception {
    // Doesn't exist.
    SkylarkModule ann = SkylarkInterfaceUtils.getSkylarkModule(MockClassZ.class);
    Class<?> cls = SkylarkInterfaceUtils.getParentWithSkylarkModule(MockClassZ.class);
    assertThat(ann).isNull();
    assertThat(cls).isNull();
  }

  @Test
  public void testGetSkylarkCallableBasic() throws Exception {
    // Normal case. Ensure two-arg form is consistent with one-arg form.
    Method method = MockClassA.class.getMethod("foo");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA#foo");

    SkylarkCallable ann2 = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann2).isEqualTo(ann);
  }

  @Test
  public void testGetSkylarkCallableSubclass() throws Exception {
    // Subclass's annotation is used.
    Method method = MockClassC.class.getMethod("foo");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassC#foo");
  }

  @Test
  public void testGetSkylarkCallableSubclassNoSubannotation() throws Exception {
    // Falls back on superclass's annotation. Superclass takes precedence over interface.
    Method method = MockClassC.class.getMethod("bar");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA#bar");
  }

  @Test
  public void testGetSkylarkCallableTwoargForm() throws Exception {
    // Ensure that when passing superclass in directly, we bypass subclass's annotation.
    Method method = MockClassC.class.getMethod("foo");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockClassA#foo");
  }

  @Test
  public void testGetSkylarkCallableNotFound() throws Exception {
    // Null result when no annotation present...
    Method method = MockClassA.class.getMethod("baz");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNull();

    // ... including when it's only present in a subclass that was bypassed...
    method = MockClassC.class.getMethod("baz");
    ann = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann).isNull();

    // ... or when the method itself is only in the subclass that was bypassed.
    method = MockClassC.class.getMethod("qux");
    ann = SkylarkInterfaceUtils.getSkylarkCallable(MockClassA.class, method);
    assertThat(ann).isNull();
  }

  @Test
  public void testGetSkylarkCallableInterface() throws Exception {
    // Search through parent interfaces. First interface takes priority.
    Method method = MockClassC.class.getMethod("baz");
    SkylarkCallable ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockInterfaceB1#baz");

    // Make sure both are still traversed.
    method = MockClassC.class.getMethod("qux");
    ann = SkylarkInterfaceUtils.getSkylarkCallable(method);
    assertThat(ann).isNotNull();
    assertThat(ann.doc()).isEqualTo("MockInterfaceB2#qux");
  }
}
