/*
 * Copyright (C) 2019 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.car.ui.utils;

import static com.android.car.ui.core.CarUi.MIN_TARGET_API;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.DimenRes;
import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.annotation.UiThread;

import com.android.car.ui.R;
import com.android.car.ui.uxr.DrawableStateView;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * Collection of utility methods
 */
@SuppressWarnings("AndroidJdkLibsChecker")
@TargetApi(MIN_TARGET_API)
public final class CarUiUtils {

    private static final String TAG = "CarUiUtils";
    private static final String READ_ONLY_SYSTEM_PROPERTY_PREFIX = "ro.";
    /** A map to cache read-only system properties. */
    private static final SparseArray<String> READ_ONLY_SYSTEM_PROPERTY_MAP = new SparseArray<>();

    private static int[] sRestrictedState;

    /** This is a utility class */
    private CarUiUtils() {
    }

    /**
     * Reads a float value from a dimens resource. This is necessary as {@link Resources#getFloat}
     * is not currently public.
     *
     * @param res   {@link Resources} to read values from
     * @param resId Id of the dimens resource to read
     */
    public static float getFloat(Resources res, @DimenRes int resId) {
        TypedValue outValue = new TypedValue();
        res.getValue(resId, outValue, true);
        return outValue.getFloat();
    }

    /** Returns the identifier of the resolved resource assigned to the given attribute. */
    public static int getAttrResourceId(Context context, int attr) {
        return getAttrResourceId(context, /*styleResId=*/ 0, attr);
    }

    /**
     * Returns the identifier of the resolved resource assigned to the given attribute defined in
     * the given style.
     */
    public static int getAttrResourceId(Context context, @StyleRes int styleResId, int attr) {
        TypedArray ta = context.obtainStyledAttributes(styleResId, new int[]{attr});
        int resId = ta.getResourceId(0, 0);
        ta.recycle();
        return resId;
    }

    /**
     * Gets the boolean value of an Attribute from an {@link Activity Activity's}
     * {@link android.content.res.Resources.Theme}.
     */
    public static boolean getThemeBoolean(Activity activity, int attr) {
        TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{attr});

        try {
            return a.getBoolean(0, false);
        } finally {
            a.recycle();
        }
    }

    /**
     * Gets the {@link Activity} for a certain {@link Context}.
     *
     * <p>It is possible the Context is not associated with an Activity, in which case
     * this method will return null.
     */
    @Nullable
    public static Activity getActivity(@Nullable Context context) {
        while (context instanceof ContextWrapper) {
            if (context instanceof Activity) {
                return (Activity) context;
            }
            context = ((ContextWrapper) context).getBaseContext();
        }
        return null;
    }

    /**
     * It behaves similarly to {@link View#findViewById(int)}, except that on Q and below,
     * it will first resolve the id to whatever it references.
     *
     * This is to support layout RROs before the new RRO features in R.
     *
     * @param id the ID to search for
     * @return a view with given ID if found, or {@code null} otherwise
     * @see View#requireViewById(int)
     */
    @Nullable
    @UiThread
    @SuppressWarnings("TypeParameterUnusedInFormals")
    public static <T extends View> T findViewByRefId(@NonNull View root, @IdRes int id) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return root.findViewById(id);
        }

        if (id == View.NO_ID) {
            return null;
        }

        TypedValue value = new TypedValue();
        root.getResources().getValue(id, value, true);
        return root.findViewById(value.resourceId);
    }

    /**
     * It behaves similarly to {@link View#requireViewById(int)}, except that on Q and below,
     * it will first resolve the id to whatever it references.
     *
     * This is to support layout RROs before the new RRO features in R.
     *
     * @param id the ID to search for
     * @return a view with given ID
     * @see View#findViewById(int)
     */
    @NonNull
    @UiThread
    @SuppressWarnings("TypeParameterUnusedInFormals")
    public static <T extends View> T requireViewByRefId(@NonNull View root, @IdRes int id) {
        T view = findViewByRefId(root, id);
        if (view == null) {
            throw new IllegalArgumentException("ID "
                    + root.getResources().getResourceName(id)
                    + " does not reference a View inside this View");
        }
        return view;
    }

    /**
     * Returns the system property of type boolean. This method converts the boolean value in string
     * returned by {@link #getSystemProperty(Resources, int)}
     */
    public static boolean getBooleanSystemProperty(
            @NonNull Resources resources, int propertyResId, boolean defaultValue) {
        String value = getSystemProperty(resources, propertyResId);

        if (!TextUtils.isEmpty(value)) {
            return Boolean.parseBoolean(value);
        }
        return defaultValue;
    }

    /**
     * Use reflection to interact with the hidden API <code>android.os.SystemProperties</code>.
     *
     * <p>This method caches read-only properties. CAVEAT: Please do not set read-only properties
     * by 'adb setprop' after app started. Read-only properties CAN BE SET ONCE if it is unset.
     * Thus, read-only properties MAY BE CHANGED from unset to set during application's lifetime if
     * you use 'adb setprop' command to set read-only properties after app started. For the sake of
     * performance, this method also caches the unset state. Otherwise, cache may not effective if
     * the system property is unset (which is most-likely).
     *
     * @param resources     resources object to fetch string
     * @param propertyResId the property resource id.
     * @return The value of the property if defined, else null. Does not return empty strings.
     */
    @Nullable
    public static String getSystemProperty(@NonNull Resources resources, int propertyResId) {
        String propertyName = resources.getString(propertyResId);
        boolean isReadOnly = propertyName.startsWith(READ_ONLY_SYSTEM_PROPERTY_PREFIX);
        if (!isReadOnly) {
            return readSystemProperty(propertyName);
        }
        synchronized (READ_ONLY_SYSTEM_PROPERTY_MAP) {
            // readOnlySystemPropertyMap may contain null values.
            if (READ_ONLY_SYSTEM_PROPERTY_MAP.indexOfKey(propertyResId) >= 0) {
                return READ_ONLY_SYSTEM_PROPERTY_MAP.get(propertyResId);
            }
            String value = readSystemProperty(propertyName);
            READ_ONLY_SYSTEM_PROPERTY_MAP.put(propertyResId, value);
            return value;
        }
    }

    @Nullable
    @SuppressLint("PrivateApi")
    private static String readSystemProperty(String propertyName) {
        Class<?> systemPropertiesClass;
        try {
            systemPropertiesClass = Class.forName("android.os.SystemProperties");
        } catch (ClassNotFoundException e) {
            Log.w(TAG, "Cannot find android.os.SystemProperties: ", e);
            return null;
        }

        Method getMethod;
        try {
            getMethod = systemPropertiesClass.getMethod("get", String.class);
        } catch (NoSuchMethodException e) {
            Log.w(TAG, "Cannot find SystemProperties.get(): ", e);
            return null;
        }

        try {
            Object[] params = new Object[]{propertyName};
            String value = (String) getMethod.invoke(systemPropertiesClass, params);
            return TextUtils.isEmpty(value) ? null : value;
        } catch (Exception e) {
            Log.w(TAG, "Failed to invoke SystemProperties.get(): ", e);
            return null;
        }
    }

    /**
     * Converts a drawable to bitmap. This value should not be null.
     */
    public static Bitmap drawableToBitmap(@NonNull Drawable drawable) {
        Bitmap bitmap;

        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            if (bitmapDrawable.getBitmap() != null) {
                return bitmapDrawable.getBitmap();
            }
        }

        if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
            bitmap = Bitmap.createBitmap(1, 1,
                    Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
        } else {
            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bitmap;
    }

    /**
     * Exact copy from Androidx.TypedArrayUtils class
     * @return The resource ID value in the {@code context} specified by {@code attr}. If it does
     * not exist, {@code fallbackAttr}.
     */
    public static int getAttr(@NonNull Context context, int attr, int fallbackAttr) {
        TypedValue value = new TypedValue();
        context.getTheme().resolveAttribute(attr, value, true);
        if (value.resourceId != 0) {
            return attr;
        }
        return fallbackAttr;
    }

    /**
     * Converts a {@link CharSequence} to a {@link String}.
     *
     * This is the same as calling {@link CharSequence#toString()}, except it will handle
     * null CharSequences, returning a null string.
     */
    public static String charSequenceToString(@Nullable CharSequence charSequence) {
        return charSequence == null ? null : charSequence.toString();
    }

    /**
     * Given a list of T and a function to convert from T to U, return a list of U.
     *
     * This will create a new list.
     */
    public static <T, U> List<U> convertList(List<T> list, Function<T, U> f) {
        if (list == null) {
            return null;
        }

        List<U> result = new ArrayList<>();
        for (T item : list) {
            result.add(f.apply(item));
        }
        return result;
    }

    /**
     * Traverses the view hierarchy, and whenever it sees a {@link DrawableStateView}, adds
     * state_ux_restricted to it.
     *
     * Note that this will remove any other drawable states added by other calls to
     * {@link DrawableStateView#setExtraDrawableState(int[], int[])}
     */
    public static void makeAllViewsUxRestricted(@Nullable View view, boolean restricted) {
        if (view == null) {
            return;
        }
        initializeRestrictedState(view);
        applyStatesToAllViews(view, restricted ? sRestrictedState : null, null);
    }

    /**
     * Traverses the view hierarchy, and whenever it sees a {@link DrawableStateView}, adds
     * the relevant state_enabled and state_ux_restricted to the view.
     *
     * Note that this will remove any other drawable states added by other calls to
     * {@link DrawableStateView#setExtraDrawableState(int[], int[])}
     */
    public static void makeAllViewsEnabledAndUxRestricted(@Nullable View view, boolean enabled,
            boolean restricted) {
        if (view == null) {
            return;
        }
        initializeRestrictedState(view);
        int[] statesToAdd = null;
        if (enabled) {
            if (restricted) {
                statesToAdd = new int[sRestrictedState.length + 1];
                statesToAdd[0] = android.R.attr.state_enabled;
                System.arraycopy(sRestrictedState, 0, statesToAdd, 1, sRestrictedState.length);
            } else {
                statesToAdd = new int[] {android.R.attr.state_enabled};
            }
        } else if (restricted) {
            statesToAdd = sRestrictedState;
        }
        int[] statesToRemove = enabled ? null : new int[] {android.R.attr.state_enabled};
        applyStatesToAllViews(view, statesToAdd, statesToRemove);
    }

    private static void initializeRestrictedState(@NonNull View view) {
        if (sRestrictedState != null) {
            return;
        }
        int androidStateUxRestricted = view.getResources()
                .getIdentifier("state_ux_restricted", "attr", "android");

        if (androidStateUxRestricted == 0) {
            sRestrictedState = new int[] { R.attr.state_ux_restricted };
        } else {
            sRestrictedState = new int[] {
                    R.attr.state_ux_restricted,
                    androidStateUxRestricted
            };
        }
    }

    private static void applyStatesToAllViews(@NonNull View view, int[] statesToAdd,
            int[] statesToRemove) {
        if (view instanceof DrawableStateView) {
            ((DrawableStateView) view).setExtraDrawableState(statesToAdd, statesToRemove);
        }
        if (view instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) view;
            for (int i = 0; i < vg.getChildCount(); i++) {
                applyStatesToAllViews(vg.getChildAt(i), statesToAdd, statesToRemove);
            }
        }
    }
}
