/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * 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.android.dx.mockito;

import android.os.Build;
import android.util.Log;

import com.android.dx.stock.ProxyBuilder;
import org.mockito.exceptions.base.MockitoException;
import org.mockito.exceptions.stacktrace.StackTraceCleaner;
import org.mockito.internal.util.reflection.LenientCopyTool;
import org.mockito.invocation.MockHandler;
import org.mockito.mock.MockCreationSettings;
import org.mockito.plugins.MockMaker;
import org.mockito.plugins.StackTraceCleanerProvider;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Set;

/**
 * Generates mock instances on Android's runtime.
 */
public final class DexmakerMockMaker implements MockMaker, StackTraceCleanerProvider {
    private static final String LOG_TAG = DexmakerMockMaker.class.getSimpleName();

    private final UnsafeAllocator unsafeAllocator = UnsafeAllocator.create();

    public DexmakerMockMaker() {
        if (Build.VERSION.SDK_INT >= 28) {
            // Blacklisted APIs were introduced in Android P:
            //
            // https://android-developers.googleblog.com/2018/02/
            // improving-stability-by-reducing-usage.html
            //
            // This feature prevents access to blacklisted fields and calling of blacklisted APIs
            // if the calling class is not trusted.
            Method allowHiddenApiReflectionFromMethod;
            try {
                Class vmDebug = Class.forName("dalvik.system.VMDebug");
                allowHiddenApiReflectionFromMethod = vmDebug.getDeclaredMethod(
                        "allowHiddenApiReflectionFrom", Class.class);
            } catch (ClassNotFoundException | NoSuchMethodException e) {
                throw new IllegalStateException(
                        "Cannot find VMDebug#allowHiddenApiReflectionFrom. Method is needed to "
                                + "allow spies to copy blacklisted fields.");
            }

            // The LenientCopyTool copies the fields to a spy when creating the copy from an
            // existing object. Some of the fields might be blacklisted. Marking the LenientCopyTool
            // as trusted allows the tool to copy all fields, including the blacklisted ones.
            try {
                allowHiddenApiReflectionFromMethod.invoke(null, LenientCopyTool.class);
            } catch (InvocationTargetException | IllegalAccessException e) {
                Log.w(LOG_TAG, "Cannot allow LenientCopyTool to copy spies of blacklisted fields. "
                        + "This might break spying on system classes.");
            }
        }
    }

    @Override
    public <T> T createMock(MockCreationSettings<T> settings, MockHandler handler) {
        Class<T> typeToMock = settings.getTypeToMock();
        Set<Class<?>> interfacesSet = settings.getExtraInterfaces();
        Class<?>[] extraInterfaces = interfacesSet.toArray(new Class[interfacesSet.size()]);
        InvocationHandler invocationHandler = new InvocationHandlerAdapter(handler);

        if (typeToMock.isInterface()) {
            // support interfaces via java.lang.reflect.Proxy
            Class[] classesToMock = new Class[extraInterfaces.length + 1];
            classesToMock[0] = typeToMock;
            System.arraycopy(extraInterfaces, 0, classesToMock, 1, extraInterfaces.length);
            // newProxyInstance returns the type of typeToMock
            @SuppressWarnings("unchecked")
            T mock = (T) Proxy.newProxyInstance(typeToMock.getClassLoader(), classesToMock, invocationHandler);
            return mock;

        } else {
            // support concrete classes via dexmaker's ProxyBuilder
            try {
                ProxyBuilder b = ProxyBuilder.forClass(typeToMock)
                        .implementing(extraInterfaces);

                if (Boolean.parseBoolean(
                        System.getProperty("dexmaker.share_classloader", "false"))) {
                    b.withSharedClassLoader();
                }

                Class<? extends T> proxyClass = b.buildProxyClass();
                T mock = unsafeAllocator.newInstance(proxyClass);
                ProxyBuilder.setInvocationHandler(mock, invocationHandler);
                return mock;
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new MockitoException("Failed to mock " + typeToMock, e);
            }
        }
    }

    @Override
    public void resetMock(Object mock, MockHandler newHandler, MockCreationSettings settings) {
        InvocationHandlerAdapter adapter = getInvocationHandlerAdapter(mock);
        adapter.setHandler(newHandler);
    }

    @Override
    public TypeMockability isTypeMockable(final Class<?> type) {
        return new TypeMockability() {
            @Override
            public boolean mockable() {
                return !type.isPrimitive() && !Modifier.isFinal(type.getModifiers());
            }

            @Override
            public String nonMockableReason() {
                if (type.isPrimitive()) {
                    return "primitive type";
                }

                if (Modifier.isFinal(type.getModifiers())) {
                    return "final or anonymous class";
                }

                return "not handled type";
            }
        };
    }

    @Override
    public MockHandler getHandler(Object mock) {
        InvocationHandlerAdapter adapter = getInvocationHandlerAdapter(mock);
        return adapter != null ? adapter.getHandler() : null;
    }

    @Override
    public StackTraceCleaner getStackTraceCleaner(final StackTraceCleaner defaultCleaner) {
        return new StackTraceCleaner() {
            @Override
            public boolean isIn(StackTraceElement candidate) {
                String className = candidate.getClassName();

                return defaultCleaner.isIn(candidate)
                        && !className.endsWith("_Proxy") // dexmaker class proxies
                        && !className.startsWith("$Proxy") // dalvik interface proxies
                        && !className.startsWith("java.lang.reflect.Proxy")
                        && !(className.startsWith("com.android.dx.mockito.")
                             // Do not clean unit tests
                             && !className.startsWith("com.android.dx.mockito.tests"));
            }
        };
    }

    private InvocationHandlerAdapter getInvocationHandlerAdapter(Object mock) {
        if (mock == null) {
            return null;
        }
        if (Proxy.isProxyClass(mock.getClass())) {
            InvocationHandler invocationHandler = Proxy.getInvocationHandler(mock);
            return invocationHandler instanceof InvocationHandlerAdapter
                    ? (InvocationHandlerAdapter) invocationHandler
                    : null;
        }

        if (ProxyBuilder.isProxyClass(mock.getClass())) {
            InvocationHandler invocationHandler = ProxyBuilder.getInvocationHandler(mock);
            return invocationHandler instanceof InvocationHandlerAdapter
                    ? (InvocationHandlerAdapter) invocationHandler
                    : null;
        }

        return null;
    }
}
