/*
 * 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 com.android.car.apps.common;

import static android.content.pm.PackageManager.MATCH_ALL;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent.ShortcutIconResource;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.text.TextUtils;

import androidx.annotation.Nullable;

/**
 * Utilities for working with URIs.
 */
public final class UriUtils {

    private static final String SCHEME_SHORTCUT_ICON_RESOURCE = "shortcut.icon.resource";
    private static final String SCHEME_DELIMITER = "://";
    private static final String URI_PATH_DELIMITER = "/";
    private static final String URI_PACKAGE_DELIMITER = ":";
    private static final String HTTP_PREFIX = "http";
    private static final String HTTPS_PREFIX = "https";
    private static final String SCHEME_ACCOUNT_IMAGE = "image.account";
    private static final String ACCOUNT_IMAGE_CHANGE_NOTIFY_URI = "change_notify_uri";
    private static final String DETAIL_DIALOG_URI_DIALOG_TITLE = "detail_dialog_title";
    private static final String DETAIL_DIALOG_URI_DIALOG_DESCRIPTION = "detail_dialog_description";
    private static final String DETAIL_DIALOG_URI_DIALOG_ACTION_START_INDEX =
            "detail_dialog_action_start_index";
    private static final String DETAIL_DIALOG_URI_DIALOG_ACTION_START_NAME =
            "detail_dialog_action_start_name";

    /**
     * Non instantiable.
     */
    private UriUtils() {}

    /** Returns true if the uri is null or empty. */
    public static boolean isEmpty(@Nullable Uri uri) {
        return (uri == null || TextUtils.isEmpty(uri.toString()));
    }

    /**
     * Gets resource uri representation for a resource of a package
     */
    public static String getAndroidResourceUri(Context context, int resourceId) {
        return getAndroidResourceUri(context.getResources(), resourceId);
    }

    /**
     * Gets resource uri representation for a resource
     */
    public static String getAndroidResourceUri(Resources resources, int resourceId) {
        return ContentResolver.SCHEME_ANDROID_RESOURCE
                + SCHEME_DELIMITER + resources.getResourceName(resourceId)
                        .replace(URI_PACKAGE_DELIMITER, URI_PATH_DELIMITER);
    }

    /**
     * Loads drawable from resource
     */
    @Nullable
    public static Drawable getDrawable(Context context, ShortcutIconResource r) {
        Resources resources = null;
        try {
            resources = context.getPackageManager().getResourcesForApplication(r.packageName);
        } catch (NameNotFoundException e) {
            // Return null below.
        }
        if (resources == null) {
            return null;
        }
        final int id = resources.getIdentifier(r.resourceName, null, null);
        return resources.getDrawable(id, null);
    }

    /**
     * Gets a URI with short cut icon scheme.
     */
    public static Uri getShortcutIconResourceUri(ShortcutIconResource iconResource) {
        return Uri.parse(SCHEME_SHORTCUT_ICON_RESOURCE + SCHEME_DELIMITER + iconResource.packageName
                + URI_PATH_DELIMITER
                + iconResource.resourceName.replace(URI_PACKAGE_DELIMITER, URI_PATH_DELIMITER));
    }

    /**
     * Gets a URI with scheme = {@link ContentResolver#SCHEME_ANDROID_RESOURCE} for
     * a full resource name. This name is a single string of the form "package:type/entry".
     */
    public static Uri getAndroidResourceUri(String resourceName) {
        Uri uri = Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + SCHEME_DELIMITER
                + resourceName.replace(URI_PACKAGE_DELIMITER, URI_PATH_DELIMITER));
        return uri;
    }

    /**
     * Checks if the URI refers to an Android resource.
     */
    public static boolean isAndroidResourceUri(Uri uri) {
        return ContentResolver.SCHEME_ANDROID_RESOURCE.equals(uri.getScheme());
    }

    /**
     * Gets a URI with the account image scheme.
     * @hide
     */
    public static Uri getAccountImageUri(String accountName) {
        Uri uri = Uri.parse(SCHEME_ACCOUNT_IMAGE + SCHEME_DELIMITER + accountName);
        return uri;
    }

    /**
     * Gets a URI with the account image scheme, and specifying an URI to be
     * used in notifyChange() when the image pointed to by the returned URI is
     * updated.
     * @hide
     */
    public static Uri getAccountImageUri(String accountName, Uri changeNotifyUri) {
        Uri uri = Uri.parse(SCHEME_ACCOUNT_IMAGE + SCHEME_DELIMITER + accountName);
        if (changeNotifyUri != null) {
            uri = uri.buildUpon().appendQueryParameter(ACCOUNT_IMAGE_CHANGE_NOTIFY_URI,
                    changeNotifyUri.toString()).build();
        }
        return uri;
    }

    /**
     * Checks if the URI refers to an account image.
     * @hide
     */
    public static boolean isAccountImageUri(Uri uri) {
        return uri == null ? false : SCHEME_ACCOUNT_IMAGE.equals(uri.getScheme());
    }

    /**
     * @hide
     */
    public static String getAccountName(Uri uri) {
        if (isAccountImageUri(uri)) {
            String accountName = uri.getAuthority() + uri.getPath();
            return accountName;
        } else {
            throw new IllegalArgumentException("Invalid account image URI. " + uri);
        }
    }

    /**
     * @hide
     */
    public static Uri getAccountImageChangeNotifyUri(Uri uri) {
        if (isAccountImageUri(uri)) {
            String notifyUri = uri.getQueryParameter(ACCOUNT_IMAGE_CHANGE_NOTIFY_URI);
            if (notifyUri == null) {
                return null;
            } else {
                return Uri.parse(notifyUri);
            }
        } else {
            throw new IllegalArgumentException("Invalid account image URI. " + uri);
        }
    }

    /**
     * Finds the packageName of the application to which the content authority of the given uri
     * belongs to.
     */
    @Nullable
    public static String getPackageName(Context context, Uri uri) {
        PackageManager pm = context.getPackageManager();
        ProviderInfo info = pm.resolveContentProvider(uri.getAuthority(), MATCH_ALL);
        // Info can be null when the app doesn't define a provider.
        return (info != null) ? info.packageName : uri.getAuthority();
    }

    /**
     * Returns {@code true} if the URI refers to a content URI which can be opened via
     * {@link ContentResolver#openInputStream(Uri)}.
     */
    public static boolean isContentUri(Uri uri) {
        return ContentResolver.SCHEME_CONTENT.equals(uri.getScheme()) ||
                ContentResolver.SCHEME_FILE.equals(uri.getScheme());
    }

    /**
     * Checks if the URI refers to an shortcut icon resource.
     */
    public static boolean isShortcutIconResourceUri(Uri uri) {
        return SCHEME_SHORTCUT_ICON_RESOURCE.equals(uri.getScheme());
    }

    /**
     * Creates a shortcut icon resource object from an Android resource URI.
     */
    public static ShortcutIconResource getIconResource(Context context, Uri uri) {
        if(isAndroidResourceUri(uri)) {
            ShortcutIconResource iconResource = new ShortcutIconResource();
            iconResource.packageName = getPackageName(context, uri);
            // Trim off the scheme + 3 extra for "://" + authority, then replace the first "/"
            // with a ":" and add to packageName.
            int resStart = ContentResolver.SCHEME_ANDROID_RESOURCE.length()
                    + SCHEME_DELIMITER.length() + uri.getAuthority().length();
            iconResource.resourceName = iconResource.packageName
                    + uri.toString().substring(resStart)
                            .replaceFirst(URI_PATH_DELIMITER, URI_PACKAGE_DELIMITER);
            return iconResource;
        } else if(isShortcutIconResourceUri(uri)) {
            ShortcutIconResource iconResource = new ShortcutIconResource();
            iconResource.packageName = getPackageName(context, uri);
            iconResource.resourceName = uri.toString().substring(
                    SCHEME_SHORTCUT_ICON_RESOURCE.length() + SCHEME_DELIMITER.length()
                    + uri.getAuthority().length() + URI_PATH_DELIMITER.length())
                    .replaceFirst(URI_PATH_DELIMITER, URI_PACKAGE_DELIMITER);
            return iconResource;
        } else {
            throw new IllegalArgumentException("Invalid resource URI. " + uri);
        }
    }

    /**
     * Returns {@code true} if this is a web URI.
     */
    public static boolean isWebUri(Uri resourceUri) {
        String scheme = resourceUri.getScheme() == null ? null
                : resourceUri.getScheme().toLowerCase();
        return HTTP_PREFIX.equals(scheme) || HTTPS_PREFIX.equals(scheme);
    }

    /**
     * Build a Uri for canvas details subactions dialog given content uri and optional parameters.
     * @param uri the subactions ContentUri
     * @param dialogTitle the custom subactions dialog title. If the value is null, canvas will
     *        fall back to use previous action's name as the subactions dialog title.
     * @param dialogDescription the custom subactions dialog description. If the value is null,
     *        canvas will fall back to use previous action's subname as the subactions dialog
     *        description.
     * @hide
     */
    public static Uri getSubactionDialogUri(Uri uri, String dialogTitle, String dialogDescription) {
        return getSubactionDialogUri(uri, dialogTitle, dialogDescription, null, -1);
    }

    /**
     * Build a Uri for canvas details subactions dialog given content uri and optional parameters.
     * @param uri the subactions ContentUri
     * @param dialogTitle the custom subactions dialog title. If the value is null, canvas will
     *        fall back to use previous action's name as the subactions dialog title.
     * @param dialogDescription the custom subactions dialog description. If the value is null,
     *        canvas will fall back to use previous action's subname as the subactions dialog
     *        description.
     * @param startIndex the focused action in actions list when started.
     * @hide
     */
    public static Uri getSubactionDialogUri(Uri uri, String dialogTitle, String dialogDescription,
            int startIndex) {
        return getSubactionDialogUri(uri, dialogTitle, dialogDescription, null, startIndex);
    }

    /**
     * Build a Uri for canvas details subactions dialog given content uri and optional parameters.
     * @param uri the subactions ContentUri
     * @param dialogTitle the custom subactions dialog title. If the value is null, canvas will
     *        fall back to use previous action's name as the subactions dialog title.
     * @param dialogDescription the custom subactions dialog description. If the value is null,
     *        canvas will fall back to use previous action's subname as the subactions dialog
     *        description.
     * @param startName the name of action that is focused in actions list when started.
     * @hide
     */
    public static Uri getSubactionDialogUri(Uri uri, String dialogTitle, String dialogDescription,
            String startName) {
        return getSubactionDialogUri(uri, dialogTitle, dialogDescription, startName, -1);
    }

    /**
     * Build a Uri for canvas details subactions dialog given content uri and optional parameters.
     * @param uri the subactions ContentUri
     * @param dialogTitle the custom subactions dialog title. If the value is null, canvas will
     *        fall back to use previous action's name as the subactions dialog title.
     * @param dialogDescription the custom subactions dialog description. If the value is null,
     *        canvas will fall back to use previous action's subname as the subactions dialog
     *        description.
     * @param startIndex the focused action in actions list when started.
     * @param startName the name of action that is focused in actions list when started. startName
     *        takes priority over start index.
     * @hide
     */
    public static Uri getSubactionDialogUri(Uri uri, String dialogTitle, String dialogDescription,
            String startName, int startIndex) {
        if (uri == null || !isContentUri(uri)) {
            // If given uri is null, or it is not of contentUri type, return null.
            return null;
        }

        Uri.Builder builder = uri.buildUpon();
        if (!TextUtils.isEmpty(dialogTitle)) {
            builder.appendQueryParameter(DETAIL_DIALOG_URI_DIALOG_TITLE, dialogTitle);
        }

        if (!TextUtils.isEmpty(DETAIL_DIALOG_URI_DIALOG_DESCRIPTION)) {
            builder.appendQueryParameter(DETAIL_DIALOG_URI_DIALOG_DESCRIPTION, dialogDescription);
        }

        if (startIndex != -1) {
            builder.appendQueryParameter(DETAIL_DIALOG_URI_DIALOG_ACTION_START_INDEX,
                    Integer.toString(startIndex));
        }

        if (!TextUtils.isEmpty(startName)) {
            builder.appendQueryParameter(DETAIL_DIALOG_URI_DIALOG_ACTION_START_NAME, startName);
        }

        return builder.build();
    }

    /**
     * Get subaction dialog title parameter from URI
     * @param uri ContentUri for canvas details subactions
     * @return custom dialog title if this parameter is available in URI. Otherwise, return null.
     * @hide
     */
    public static String getSubactionDialogTitle(Uri uri) {
        if (uri == null || !isContentUri(uri)) {
            return null;
        }

        return uri.getQueryParameter(DETAIL_DIALOG_URI_DIALOG_TITLE);
    }

    /**
     * Get subaction dialog description parameter from URI
     * @param uri ContentUri for canvas details subactions
     * @return custom dialog description if this parameter is available in URI.
     * Otherwise, return null.
     * @hide
     */
    public static String getSubactionDialogDescription(Uri uri) {
        if (uri == null || !isContentUri(uri)) {
            return null;
        }

        return uri.getQueryParameter(DETAIL_DIALOG_URI_DIALOG_DESCRIPTION);
    }

    /**
     * Get subaction dialog action list focused index when started from URI
     * @param uri ContentUri for canvas details subactions
     * @return action starting index if this parameter is available in URI. Otherwise, return -1.
     * @hide
     */
    public static int getSubactionDialogActionStartIndex(Uri uri) {
        if (uri == null || !isContentUri(uri)) {
            return -1;
        }

        String startIndexStr = uri.getQueryParameter(DETAIL_DIALOG_URI_DIALOG_ACTION_START_INDEX);
        if (!TextUtils.isEmpty(startIndexStr) && TextUtils.isDigitsOnly(startIndexStr)) {
            return Integer.parseInt(startIndexStr);
        } else {
            return -1;
        }
    }

    /**
     * Get subaction dialog action list focused action name when started from URI
     * @param uri ContentUri for canvas details subactions
     * @return that name of starting action if this parameter is available in URI.
     * Otherwise, return null.
     * @hide
     */
    public static String getSubactionDialogActionStartName(Uri uri) {
        if (uri == null || !isContentUri(uri)) {
            return null;
        }

        return uri.getQueryParameter(DETAIL_DIALOG_URI_DIALOG_ACTION_START_NAME);
    }
}
