package net.bytebuddy.implementation.auxiliary;

import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.MethodAccessorFactory;
import net.bytebuddy.utility.RandomString;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.objectweb.asm.Opcodes;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

public class TrivialTypeTest {

    private static final String FOO = "foo";

    @Rule
    public MethodRule mockitoRule = MockitoJUnit.rule().silent();

    @Mock
    private ClassFileVersion classFileVersion;

    @Mock
    private MethodAccessorFactory methodAccessorFactory;

    @Test
    public void testPlain() throws Exception {
        when(classFileVersion.getMinorMajorVersion()).thenReturn(ClassFileVersion.JAVA_V5.getMinorMajorVersion());
        DynamicType dynamicType = TrivialType.PLAIN.make(FOO, classFileVersion, methodAccessorFactory);
        assertThat(dynamicType.getTypeDescription().getName(), is(FOO));
        assertThat(dynamicType.getTypeDescription().getModifiers(), is(Opcodes.ACC_SYNTHETIC));
        assertThat(dynamicType.getTypeDescription().getDeclaredAnnotations().size(), is(0));
        assertThat(dynamicType.getAuxiliaryTypes().size(), is(0));
        assertThat(dynamicType.getLoadedTypeInitializers().get(dynamicType.getTypeDescription()).isAlive(), is(false));
    }

    @Test
    public void testPlainSuffix() throws Exception {
        assertThat(TrivialType.PLAIN.getSuffix(), is(RandomString.hashOf(TrivialType.PLAIN.name().hashCode())));
    }

    @Test
    public void testSignatureRelevant() throws Exception {
        when(classFileVersion.getMinorMajorVersion()).thenReturn(ClassFileVersion.JAVA_V5.getMinorMajorVersion());
        DynamicType dynamicType = TrivialType.SIGNATURE_RELEVANT.make(FOO, classFileVersion, methodAccessorFactory);
        assertThat(dynamicType.getTypeDescription().getName(), is(FOO));
        assertThat(dynamicType.getTypeDescription().getModifiers(), is(Opcodes.ACC_SYNTHETIC));
        assertThat(dynamicType.getTypeDescription().getDeclaredAnnotations().size(), is(1));
        assertThat(dynamicType.getTypeDescription().getDeclaredAnnotations().isAnnotationPresent(AuxiliaryType.SignatureRelevant.class), is(true));
        assertThat(dynamicType.getAuxiliaryTypes().size(), is(0));
        assertThat(dynamicType.getLoadedTypeInitializers().get(dynamicType.getTypeDescription()).isAlive(), is(false));
    }

    @Test
    public void testSignatureRelevantSuffix() throws Exception {
        assertThat(TrivialType.SIGNATURE_RELEVANT.getSuffix(), is(RandomString.hashOf(TrivialType.SIGNATURE_RELEVANT.name().hashCode())));
    }
}
