/*
 * Copyright (c) 2017 Mockito contributors
 * This program is made available under the terms of the MIT License.
 */
package org.mockito.internal.creation.bytebuddy;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.ClassFileVersion;
import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.StubMethod;
import org.junit.Test;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.internal.creation.MockSettingsImpl;
import org.mockito.internal.creation.settings.CreationSettings;
import org.mockito.internal.handler.MockHandlerImpl;
import org.mockito.internal.stubbing.answers.Returns;
import org.mockito.internal.util.collections.Sets;
import org.mockito.mock.MockCreationSettings;
import org.mockito.mock.SerializableMode;
import org.mockito.plugins.MockMaker;

import java.util.*;
import java.util.regex.Pattern;

import static net.bytebuddy.ClassFileVersion.JAVA_V8;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.junit.Assume.assumeTrue;

public class InlineByteBuddyMockMakerTest extends AbstractByteBuddyMockMakerTest<InlineByteBuddyMockMaker> {

    public InlineByteBuddyMockMakerTest() {
        super(new InlineByteBuddyMockMaker());
    }

    @Override
    protected Class<?> mockTypeOf(Class<?> type) {
        return type;
    }

    @Test
    public void should_create_mock_from_final_class() throws Exception {
        MockCreationSettings<FinalClass> settings = settingsFor(FinalClass.class);
        FinalClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<FinalClass>(settings));
        assertThat(proxy.foo()).isEqualTo("bar");
    }

    @Test
    public void should_create_mock_from_final_class_in_the_JDK() throws Exception {
        MockCreationSettings<Pattern> settings = settingsFor(Pattern.class);
        Pattern proxy = mockMaker.createMock(settings, new MockHandlerImpl<Pattern>(settings));
        assertThat(proxy.pattern()).isEqualTo("bar");
    }

    @Test
    public void should_create_mock_from_abstract_class_with_final_method() throws Exception {
        MockCreationSettings<FinalMethodAbstractType> settings = settingsFor(FinalMethodAbstractType.class);
        FinalMethodAbstractType proxy = mockMaker.createMock(settings, new MockHandlerImpl<FinalMethodAbstractType>(settings));
        assertThat(proxy.foo()).isEqualTo("bar");
        assertThat(proxy.bar()).isEqualTo("bar");
    }

    @Test
    public void should_create_mock_from_final_class_with_interface_methods() throws Exception {
        MockCreationSettings<FinalMethod> settings = settingsFor(FinalMethod.class, SampleInterface.class);
        FinalMethod proxy = mockMaker.createMock(settings, new MockHandlerImpl<FinalMethod>(settings));
        assertThat(proxy.foo()).isEqualTo("bar");
        assertThat(((SampleInterface) proxy).bar()).isEqualTo("bar");
    }

    @Test
    public void should_detect_non_overridden_generic_method_of_supertype() throws Exception {
        MockCreationSettings<GenericSubClass> settings = settingsFor(GenericSubClass.class);
        GenericSubClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<GenericSubClass>(settings));
        assertThat(proxy.value()).isEqualTo("bar");
    }

    @Test
    public void should_create_mock_from_hashmap() throws Exception {
        MockCreationSettings<HashMap> settings = settingsFor(HashMap.class);
        HashMap proxy = mockMaker.createMock(settings, new MockHandlerImpl<HashMap>(settings));
        assertThat(proxy.get(null)).isEqualTo("bar");
    }

    @Test
    @SuppressWarnings("unchecked")
    public void should_throw_exception_redefining_unmodifiable_class() {
        MockCreationSettings settings = settingsFor(int.class);
        try {
            mockMaker.createMock(settings, new MockHandlerImpl(settings));
            fail("Expected a MockitoException");
        } catch (MockitoException e) {
            e.printStackTrace();
            assertThat(e).hasMessageContaining("Could not modify all classes");
        }
    }

    @Test
    @SuppressWarnings("unchecked")
    public void should_throw_exception_redefining_array() {
        int[] array = new int[5];
        MockCreationSettings<? extends int[]> settings = settingsFor(array.getClass());
        try {
            mockMaker.createMock(settings, new MockHandlerImpl(settings));
            fail("Expected a MockitoException");
        } catch (MockitoException e) {
            assertThat(e).hasMessageContaining("Arrays cannot be mocked");
        }
    }

    @Test
    public void should_create_mock_from_enum() throws Exception {
        MockCreationSettings<EnumClass> settings = settingsFor(EnumClass.class);
        EnumClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<EnumClass>(settings));
        assertThat(proxy.foo()).isEqualTo("bar");
    }

    @Test
    public void should_fail_at_creating_a_mock_of_a_final_class_with_explicit_serialization() throws Exception {
        MockCreationSettings<FinalClass> settings = new CreationSettings<FinalClass>()
                .setTypeToMock(FinalClass.class)
                .setSerializableMode(SerializableMode.BASIC);

        try {
            mockMaker.createMock(settings, new MockHandlerImpl<FinalClass>(settings));
            fail("Expected a MockitoException");
        } catch (MockitoException e) {
            assertThat(e)
                    .hasMessageContaining("Unsupported settings")
                    .hasMessageContaining("serialization")
                    .hasMessageContaining("extra interfaces");
        }
    }

    @Test
    public void should_fail_at_creating_a_mock_of_a_final_class_with_extra_interfaces() throws Exception {
        MockCreationSettings<FinalClass> settings = new CreationSettings<FinalClass>()
                .setTypeToMock(FinalClass.class)
                .setExtraInterfaces(Sets.<Class<?>>newSet(List.class));

        try {
            mockMaker.createMock(settings, new MockHandlerImpl<FinalClass>(settings));
            fail("Expected a MockitoException");
        } catch (MockitoException e) {
            assertThat(e)
                    .hasMessageContaining("Unsupported settings")
                    .hasMessageContaining("serialization")
                    .hasMessageContaining("extra interfaces");
        }
    }

    @Test
    public void should_mock_interface() {
        MockSettingsImpl<Set> mockSettings = new MockSettingsImpl<Set>();
        mockSettings.setTypeToMock(Set.class);
        mockSettings.defaultAnswer(new Returns(10));
        Set<?> proxy = mockMaker.createMock(mockSettings, new MockHandlerImpl<Set>(mockSettings));

        assertThat(proxy.size()).isEqualTo(10);
    }

    @Test
    public void should_mock_interface_to_string() {
        MockSettingsImpl<Set> mockSettings = new MockSettingsImpl<Set>();
        mockSettings.setTypeToMock(Set.class);
        mockSettings.defaultAnswer(new Returns("foo"));
        Set<?> proxy = mockMaker.createMock(mockSettings, new MockHandlerImpl<Set>(mockSettings));

        assertThat(proxy.toString()).isEqualTo("foo");
    }

    @Test
    public void should_remove_recursive_self_call_from_stack_trace() throws Exception {
        StackTraceElement[] stack = new StackTraceElement[]{
                new StackTraceElement("foo", "", "", -1),
                new StackTraceElement(SampleInterface.class.getName(), "", "", -1),
                new StackTraceElement("qux", "", "", -1),
                new StackTraceElement("bar", "", "", -1),
                new StackTraceElement("baz", "", "", -1)
        };

        Throwable throwable = new Throwable();
        throwable.setStackTrace(stack);
        throwable = MockMethodAdvice.hideRecursiveCall(throwable, 2, SampleInterface.class);

        assertThat(throwable.getStackTrace()).isEqualTo(new StackTraceElement[]{
                new StackTraceElement("foo", "", "", -1),
                new StackTraceElement("bar", "", "", -1),
                new StackTraceElement("baz", "", "", -1)
        });
    }

    @Test
    public void should_handle_missing_or_inconsistent_stack_trace() throws Exception {
        Throwable throwable = new Throwable();
        throwable.setStackTrace(new StackTraceElement[0]);
        assertThat(MockMethodAdvice.hideRecursiveCall(throwable, 0, SampleInterface.class)).isSameAs(throwable);
    }

    @Test
    public void should_provide_reason_for_wrapper_class() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(Integer.class);
        assertThat(mockable.nonMockableReason()).isEqualTo("Cannot mock wrapper types, String.class or Class.class");
    }

    @Test
    public void should_provide_reason_for_vm_unsupported() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(int[].class);
        assertThat(mockable.nonMockableReason()).isEqualTo("VM does not not support modification of given type");
    }

    @Test
    public void should_mock_method_of_package_private_class() throws Exception {
        MockCreationSettings<NonPackagePrivateSubClass> settings = settingsFor(NonPackagePrivateSubClass.class);
        NonPackagePrivateSubClass proxy = mockMaker.createMock(settings, new MockHandlerImpl<NonPackagePrivateSubClass>(settings));
        assertThat(proxy.value()).isEqualTo("bar");
    }

    @Test
    public void is_type_mockable_excludes_String() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(String.class);
        assertThat(mockable.mockable()).isFalse();
        assertThat(mockable.nonMockableReason()).contains("Cannot mock wrapper types, String.class or Class.class");
    }

    @Test
    public void is_type_mockable_excludes_Class() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(Class.class);
        assertThat(mockable.mockable()).isFalse();
        assertThat(mockable.nonMockableReason()).contains("Cannot mock wrapper types, String.class or Class.class");
    }

    @Test
    public void is_type_mockable_excludes_primitive_classes() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(int.class);
        assertThat(mockable.mockable()).isFalse();
        assertThat(mockable.nonMockableReason()).contains("primitive");
    }

    @Test
    public void is_type_mockable_allows_anonymous() {
        Observer anonymous = new Observer() {
            @Override
            public void update(Observable o, Object arg) {
            }
        };
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(anonymous.getClass());
        assertThat(mockable.mockable()).isTrue();
        assertThat(mockable.nonMockableReason()).contains("");
    }

    @Test
    public void is_type_mockable_give_empty_reason_if_type_is_mockable() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(SomeClass.class);
        assertThat(mockable.mockable()).isTrue();
        assertThat(mockable.nonMockableReason()).isEqualTo("");
    }

    @Test
    public void is_type_mockable_give_allow_final_mockable_from_JDK() {
        MockMaker.TypeMockability mockable = mockMaker.isTypeMockable(Pattern.class);
        assertThat(mockable.mockable()).isTrue();
        assertThat(mockable.nonMockableReason()).isEqualTo("");
    }

    @Test
    public void test_parameters_retention() throws Exception {
        assumeTrue(ClassFileVersion.ofThisVm().isAtLeast(JAVA_V8));

        Class<?> typeWithParameters = new ByteBuddy()
                .subclass(Object.class)
                .defineMethod("foo", void.class, Visibility.PUBLIC)
                .withParameter(String.class, "bar")
                .intercept(StubMethod.INSTANCE)
                .make()
                .load(null)
                .getLoaded();

        MockCreationSettings<?> settings = settingsFor(typeWithParameters);
        @SuppressWarnings("unchecked")
        Object proxy = mockMaker.createMock(settings, new MockHandlerImpl(settings));

        assertThat(proxy.getClass()).isEqualTo(typeWithParameters);
        assertThat(new TypeDescription.ForLoadedType(typeWithParameters).getDeclaredMethods().filter(named("foo"))
                .getOnly().getParameters().getOnly().getName()).isEqualTo("bar");
    }

    private static <T> MockCreationSettings<T> settingsFor(Class<T> type, Class<?>... extraInterfaces) {
        MockSettingsImpl<T> mockSettings = new MockSettingsImpl<T>();
        mockSettings.setTypeToMock(type);
        mockSettings.defaultAnswer(new Returns("bar"));
        if (extraInterfaces.length > 0) mockSettings.extraInterfaces(extraInterfaces);
        return mockSettings;
    }

    @Test
    public void testMockDispatcherIsRelocated() throws Exception {
        assertThat(InlineByteBuddyMockMaker.class.getClassLoader().getResource("org/mockito/internal/creation/bytebuddy/MockMethodDispatcher.raw")).isNotNull();
    }

    private static final class FinalClass {

        public String foo() {
            return "foo";
        }
    }

    private enum EnumClass {

        INSTANCE;

        public String foo() {
            return "foo";
        }
    }

    private abstract static class FinalMethodAbstractType {

        public final String foo() {
            return "foo";
        }

        public abstract String bar();
    }

    private static class FinalMethod {

        public final String foo() {
            return "foo";
        }
    }

    private interface SampleInterface {

        String bar();
    }

    /*package-private*/ abstract class PackagePrivateSuperClass {

        public abstract String indirect();

        public String value() {
            return indirect() + "qux";
        }
    }

    public class NonPackagePrivateSubClass extends PackagePrivateSuperClass {

        @Override
        public String indirect() {
            return "foo";
        }
    }

    public static class GenericClass<T> {

        public T value() {
            return null;
        }
    }

    public static class GenericSubClass extends GenericClass<String> {
    }
}
