/*
 * Copyright (C) 2016 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 android.view.inputmethod;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;

import java.lang.annotation.Retention;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;

import static java.lang.annotation.RetentionPolicy.SOURCE;

/**
 * @hide
 */
public final class InputConnectionInspector {

    @Retention(SOURCE)
    @IntDef({MissingMethodFlags.GET_SELECTED_TEXT,
            MissingMethodFlags.SET_COMPOSING_REGION,
            MissingMethodFlags.COMMIT_CORRECTION,
            MissingMethodFlags.REQUEST_CURSOR_UPDATES,
            MissingMethodFlags.DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
            MissingMethodFlags.GET_HANDLER,
    })
    public @interface MissingMethodFlags {
        /**
         * {@link InputConnection#getSelectedText(int)} is available in
         * {@link android.os.Build.VERSION_CODES#GINGERBREAD} and later.
         */
        int GET_SELECTED_TEXT = 1 << 0;
        /**
         * {@link InputConnection#setComposingRegion(int, int)} is available in
         * {@link android.os.Build.VERSION_CODES#GINGERBREAD} and later.
         */
        int SET_COMPOSING_REGION = 1 << 1;
        /**
         * {@link InputConnection#commitCorrection(CorrectionInfo)} is available in
         * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and later.
         */
        int COMMIT_CORRECTION = 1 << 2;
        /**
         * {@link InputConnection#requestCursorUpdates(int)} is available in
         * {@link android.os.Build.VERSION_CODES#LOLLIPOP} and later.
         */
        int REQUEST_CURSOR_UPDATES = 1 << 3;
        /**
         * {@link InputConnection#deleteSurroundingTextInCodePoints(int, int)}} is available in
         * {@link android.os.Build.VERSION_CODES#N} and later.
         */
        int DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 1 << 4;
        /**
         * {@link InputConnection#deleteSurroundingTextInCodePoints(int, int)}} is available in
         * {@link android.os.Build.VERSION_CODES#N} and later.
         */
        int GET_HANDLER = 1 << 5;
    }

    private static final Map<Class, Integer> sMissingMethodsMap = Collections.synchronizedMap(
            new WeakHashMap<>());

    @MissingMethodFlags
    public static int getMissingMethodFlags(@Nullable final InputConnection ic) {
        if (ic == null) {
            return 0;
        }
        // Optimization for a known class.
        if (ic instanceof BaseInputConnection) {
            return 0;
        }
        // Optimization for a known class.
        if (ic instanceof InputConnectionWrapper) {
            return ((InputConnectionWrapper) ic).getMissingMethodFlags();
        }
        return getMissingMethodFlagsInternal(ic.getClass());
    }

    @MissingMethodFlags
    public static int getMissingMethodFlagsInternal(@NonNull final Class clazz) {
        final Integer cachedFlags = sMissingMethodsMap.get(clazz);
        if (cachedFlags != null) {
            return cachedFlags;
        }
        int flags = 0;
        if (!hasGetSelectedText(clazz)) {
            flags |= MissingMethodFlags.GET_SELECTED_TEXT;
        }
        if (!hasSetComposingRegion(clazz)) {
            flags |= MissingMethodFlags.SET_COMPOSING_REGION;
        }
        if (!hasCommitCorrection(clazz)) {
            flags |= MissingMethodFlags.COMMIT_CORRECTION;
        }
        if (!hasRequestCursorUpdate(clazz)) {
            flags |= MissingMethodFlags.REQUEST_CURSOR_UPDATES;
        }
        if (!hasDeleteSurroundingTextInCodePoints(clazz)) {
            flags |= MissingMethodFlags.DELETE_SURROUNDING_TEXT_IN_CODE_POINTS;
        }
        if (!hasGetHandler(clazz)) {
            flags |= MissingMethodFlags.GET_HANDLER;
        }
        sMissingMethodsMap.put(clazz, flags);
        return flags;
    }

    private static boolean hasGetSelectedText(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("getSelectedText", int.class);
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    private static boolean hasSetComposingRegion(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("setComposingRegion", int.class, int.class);
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    private static boolean hasCommitCorrection(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("commitCorrection", CorrectionInfo.class);
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    private static boolean hasRequestCursorUpdate(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("requestCursorUpdates", int.class);
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    private static boolean hasDeleteSurroundingTextInCodePoints(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("deleteSurroundingTextInCodePoints", int.class,
                    int.class);
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    private static boolean hasGetHandler(@NonNull final Class clazz) {
        try {
            final Method method = clazz.getMethod("getHandler");
            return !Modifier.isAbstract(method.getModifiers());
        } catch (NoSuchMethodException e) {
            return false;
        }
    }

    public static String getMissingMethodFlagsAsString(@MissingMethodFlags final int flags) {
        final StringBuilder sb = new StringBuilder();
        boolean isEmpty = true;
        if ((flags & MissingMethodFlags.GET_SELECTED_TEXT) != 0) {
            sb.append("getSelectedText(int)");
            isEmpty = false;
        }
        if ((flags & MissingMethodFlags.SET_COMPOSING_REGION) != 0) {
            if (!isEmpty) {
                sb.append(",");
            }
            sb.append("setComposingRegion(int, int)");
            isEmpty = false;
        }
        if ((flags & MissingMethodFlags.COMMIT_CORRECTION) != 0) {
            if (!isEmpty) {
                sb.append(",");
            }
            sb.append("commitCorrection(CorrectionInfo)");
            isEmpty = false;
        }
        if ((flags & MissingMethodFlags.REQUEST_CURSOR_UPDATES) != 0) {
            if (!isEmpty) {
                sb.append(",");
            }
            sb.append("requestCursorUpdate(int)");
            isEmpty = false;
        }
        if ((flags & MissingMethodFlags.DELETE_SURROUNDING_TEXT_IN_CODE_POINTS) != 0) {
            if (!isEmpty) {
                sb.append(",");
            }
            sb.append("deleteSurroundingTextInCodePoints(int, int)");
            isEmpty = false;
        }
        if ((flags & MissingMethodFlags.GET_HANDLER) != 0) {
            if (!isEmpty) {
                sb.append(",");
            }
            sb.append("getHandler()");
        }
        return sb.toString();
    }
}
