// Copyright 2019 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.android.desugar.nest;

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

import com.google.devtools.build.android.desugar.nest.ClassMemberKey.FieldKey;
import com.google.devtools.build.android.desugar.nest.ClassMemberKey.MethodKey;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link ClassMemberKey}. */
@RunWith(JUnit4.class)
public class ClassMemberKeyTest {

  @Test
  public void fieldKey_bridgeOfInstanceRead() {
    FieldKey fieldKey =
        FieldKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "instanceFieldOfLongType",
            /* descriptor= */ "J");
    assertThat(fieldKey.bridgeOfInstanceRead())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "instanceFieldOfLongType$bridge_getter",
                /* descriptor= */ "(La/b/Charlie;)J"));
  }

  @Test
  public void fieldKey_bridgeOfInstanceWrite() {
    FieldKey fieldKey =
        FieldKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "instanceFieldOfLongType",
            /* descriptor= */ "J");
    assertThat(fieldKey.bridgeOfInstanceWrite())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "instanceFieldOfLongType$bridge_setter",
                /* descriptor= */ "(La/b/Charlie;J)J"));
  }

  @Test
  public void fieldKey_bridgeOfStaticRead() {
    FieldKey fieldKey =
        FieldKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "staticFieldOfLongType",
            /* descriptor= */ "J");
    assertThat(fieldKey.bridgeOfStaticRead())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "staticFieldOfLongType$bridge_getter",
                /* descriptor= */ "()J"));
  }

  @Test
  public void fieldKey_bridgeOfStaticWrite() {
    FieldKey fieldKey =
        FieldKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "staticFieldOfLongType",
            /* descriptor= */ "J");
    assertThat(fieldKey.bridgeOfStaticWrite())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "staticFieldOfLongType$bridge_setter",
                /* descriptor= */ "(J)J"));
  }

  @Test
  public void methodKey_bridgeOfClassInstanceMethod() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie", /* name= */ "twoLongSum", /* descriptor= */ "(JJ)J");
    assertThat(methodKey.bridgeOfClassInstanceMethod())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "twoLongSum$bridge",
                /* descriptor= */ "(La/b/Charlie;JJ)J"));
  }

  @Test
  public void methodKey_bridgeOfClassStaticMethod() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie", /* name= */ "twoLongSum", /* descriptor= */ "(JJ)J");
    assertThat(methodKey.bridgeOfClassStaticMethod())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "twoLongSum$bridge",
                /* descriptor= */ "(JJ)J"));
  }

  @Test
  public void methodKey_bridgeOfConstructor() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie", /* name= */ "<init>", /* descriptor= */ "(JJ)V");
    assertThat(methodKey.bridgeOfConstructor())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "<init>",
                /* descriptor= */ "(JJLa/b/Charlie$NestCC;)V"));
  }

  @Test
  public void methodKey_substituteOfInterfaceInstanceMethod() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "instanceInstanceMethod",
            /* descriptor= */ "(JJ)J");
    assertThat(methodKey.substituteOfInterfaceInstanceMethod())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "a_b_Charlie$instanceInstanceMethod",
                /* descriptor= */ "(La/b/Charlie;JJ)J"));
  }

  @Test
  public void methodKey_substituteOfInterfaceStaticMethod() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie",
            /* name= */ "instanceStaticMethod",
            /* descriptor= */ "(JJ)J");
    assertThat(methodKey.substituteOfInterfaceStaticMethod())
        .isEqualTo(
            MethodKey.create(
                /* ownerClass= */ "a/b/Charlie",
                /* name= */ "a_b_Charlie$instanceStaticMethod",
                /* descriptor= */ "(JJ)J"));
  }

  @Test
  public void nestHost() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie$Depth1$Depth2",
            /* name= */ "instanceStaticMethod",
            /* descriptor= */ "(JJ)J");
    assertThat(methodKey.nestHost()).isEqualTo("a/b/Charlie");
  }

  @Test
  public void nestCompanion() {
    MethodKey methodKey =
        MethodKey.create(
            /* ownerClass= */ "a/b/Charlie$Depth1$Depth2",
            /* name= */ "instanceStaticMethod",
            /* descriptor= */ "(JJ)J");
    assertThat(methodKey.nestCompanion()).isEqualTo("a/b/Charlie$NestCC");
  }
}
