/*
 * Copyright (C) 2017 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.server.autofill.ui;

import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.metrics.LogMaker;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.service.autofill.BatchUpdates;
import android.service.autofill.CustomDescription;
import android.service.autofill.InternalOnClickAction;
import android.service.autofill.InternalTransformation;
import android.service.autofill.InternalValidator;
import android.service.autofill.SaveInfo;
import android.service.autofill.ValueFinder;
import android.text.Html;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.autofill.AutofillManager;
import android.widget.ImageView;
import android.widget.RemoteViews;
import android.widget.TextView;

import com.android.internal.R;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.server.UiThread;
import com.android.server.autofill.Helper;

import java.io.PrintWriter;
import java.util.ArrayList;

/**
 * Autofill Save Prompt
 */
final class SaveUi {

    private static final String TAG = "SaveUi";

    private static final int THEME_ID_LIGHT =
            com.android.internal.R.style.Theme_DeviceDefault_Light_Autofill_Save;
    private static final int THEME_ID_DARK =
            com.android.internal.R.style.Theme_DeviceDefault_Autofill_Save;

    public interface OnSaveListener {
        void onSave();
        void onCancel(IntentSender listener);
        void onDestroy();
    }

    /**
     * Wrapper that guarantees that only one callback action (either {@link #onSave()} or
     * {@link #onCancel(IntentSender)}) is triggered by ignoring further calls after
     * it's destroyed.
     *
     * <p>It's needed becase {@link #onCancel(IntentSender)} is always called when the Save UI
     * dialog is dismissed.
     */
    private class OneActionThenDestroyListener implements OnSaveListener {

        private final OnSaveListener mRealListener;
        private boolean mDone;

        OneActionThenDestroyListener(OnSaveListener realListener) {
            mRealListener = realListener;
        }

        @Override
        public void onSave() {
            if (sDebug) Slog.d(TAG, "OneTimeListener.onSave(): " + mDone);
            if (mDone) {
                return;
            }
            mRealListener.onSave();
        }

        @Override
        public void onCancel(IntentSender listener) {
            if (sDebug) Slog.d(TAG, "OneTimeListener.onCancel(): " + mDone);
            if (mDone) {
                return;
            }
            mRealListener.onCancel(listener);
        }

        @Override
        public void onDestroy() {
            if (sDebug) Slog.d(TAG, "OneTimeListener.onDestroy(): " + mDone);
            if (mDone) {
                return;
            }
            mDone = true;
            mRealListener.onDestroy();
        }
    }

    private final Handler mHandler = UiThread.getHandler();
    private final MetricsLogger mMetricsLogger = new MetricsLogger();

    private final @NonNull Dialog mDialog;

    private final @NonNull OneActionThenDestroyListener mListener;

    private final @NonNull OverlayControl mOverlayControl;

    private final CharSequence mTitle;
    private final CharSequence mSubTitle;
    private final PendingUi mPendingUi;
    private final String mServicePackageName;
    private final ComponentName mComponentName;
    private final boolean mCompatMode;
    private final int mThemeId;

    private boolean mDestroyed;

    SaveUi(@NonNull Context context, @NonNull PendingUi pendingUi,
           @NonNull CharSequence serviceLabel, @NonNull Drawable serviceIcon,
           @Nullable String servicePackageName, @NonNull ComponentName componentName,
           @NonNull SaveInfo info, @NonNull ValueFinder valueFinder,
           @NonNull OverlayControl overlayControl, @NonNull OnSaveListener listener,
           boolean nightMode, boolean isUpdate, boolean compatMode) {
        if (sVerbose) Slog.v(TAG, "nightMode: " + nightMode);
        mThemeId = nightMode ? THEME_ID_DARK : THEME_ID_LIGHT;
        mPendingUi= pendingUi;
        mListener = new OneActionThenDestroyListener(listener);
        mOverlayControl = overlayControl;
        mServicePackageName = servicePackageName;
        mComponentName = componentName;
        mCompatMode = compatMode;

        context = new ContextThemeWrapper(context, mThemeId);
        final LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.autofill_save, null);

        final TextView titleView = view.findViewById(R.id.autofill_save_title);

        final ArraySet<String> types = new ArraySet<>(3);
        final int type = info.getType();

        if ((type & SaveInfo.SAVE_DATA_TYPE_PASSWORD) != 0) {
            types.add(context.getString(R.string.autofill_save_type_password));
        }
        if ((type & SaveInfo.SAVE_DATA_TYPE_ADDRESS) != 0) {
            types.add(context.getString(R.string.autofill_save_type_address));
        }
        if ((type & SaveInfo.SAVE_DATA_TYPE_CREDIT_CARD) != 0) {
            types.add(context.getString(R.string.autofill_save_type_credit_card));
        }
        if ((type & SaveInfo.SAVE_DATA_TYPE_USERNAME) != 0) {
            types.add(context.getString(R.string.autofill_save_type_username));
        }
        if ((type & SaveInfo.SAVE_DATA_TYPE_EMAIL_ADDRESS) != 0) {
            types.add(context.getString(R.string.autofill_save_type_email_address));
        }

        switch (types.size()) {
            case 1:
                mTitle = Html.fromHtml(context.getString(
                        isUpdate ? R.string.autofill_update_title_with_type
                                : R.string.autofill_save_title_with_type,
                        types.valueAt(0), serviceLabel), 0);
                break;
            case 2:
                mTitle = Html.fromHtml(context.getString(
                        isUpdate ? R.string.autofill_update_title_with_2types
                                : R.string.autofill_save_title_with_2types,
                        types.valueAt(0), types.valueAt(1), serviceLabel), 0);
                break;
            case 3:
                mTitle = Html.fromHtml(context.getString(
                        isUpdate ? R.string.autofill_update_title_with_3types
                                : R.string.autofill_save_title_with_3types,
                        types.valueAt(0), types.valueAt(1), types.valueAt(2), serviceLabel), 0);
                break;
            default:
                // Use generic if more than 3 or invalid type (size 0).
                mTitle = Html.fromHtml(
                        context.getString(isUpdate ? R.string.autofill_update_title
                                : R.string.autofill_save_title, serviceLabel),
                        0);
        }
        titleView.setText(mTitle);

        setServiceIcon(context, view, serviceIcon);

        final boolean hasCustomDescription =
                applyCustomDescription(context, view, valueFinder, info);
        if (hasCustomDescription) {
            mSubTitle = null;
            if (sDebug) Slog.d(TAG, "on constructor: applied custom description");
        } else {
            mSubTitle = info.getDescription();
            if (mSubTitle != null) {
                writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_SUBTITLE, type);
                final ViewGroup subtitleContainer =
                        view.findViewById(R.id.autofill_save_custom_subtitle);
                final TextView subtitleView = new TextView(context);
                subtitleView.setText(mSubTitle);
                subtitleContainer.addView(subtitleView,
                        new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                ViewGroup.LayoutParams.WRAP_CONTENT));
                subtitleContainer.setVisibility(View.VISIBLE);
            }
            if (sDebug) Slog.d(TAG, "on constructor: title=" + mTitle + ", subTitle=" + mSubTitle);
        }

        final TextView noButton = view.findViewById(R.id.autofill_save_no);
        if (info.getNegativeActionStyle() == SaveInfo.NEGATIVE_BUTTON_STYLE_REJECT) {
            noButton.setText(R.string.save_password_notnow);
        } else {
            noButton.setText(R.string.autofill_save_no);
        }
        noButton.setOnClickListener((v) -> mListener.onCancel(info.getNegativeActionListener()));

        final TextView yesButton = view.findViewById(R.id.autofill_save_yes);
        if (isUpdate) {
            yesButton.setText(R.string.autofill_update_yes);
        }
        yesButton.setOnClickListener((v) -> mListener.onSave());

        mDialog = new Dialog(context, mThemeId);
        mDialog.setContentView(view);

        // Dialog can be dismissed when touched outside, but the negative listener should not be
        // notified (hence the null argument).
        mDialog.setOnDismissListener((d) -> mListener.onCancel(null));

        final Window window = mDialog.getWindow();
        window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
        window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
                | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
        window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS);
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        window.setGravity(Gravity.BOTTOM | Gravity.CENTER);
        window.setCloseOnTouchOutside(true);
        final WindowManager.LayoutParams params = window.getAttributes();
        params.width = WindowManager.LayoutParams.MATCH_PARENT;
        params.accessibilityTitle = context.getString(R.string.autofill_save_accessibility_title);
        params.windowAnimations = R.style.AutofillSaveAnimation;

        show();
    }

    private boolean applyCustomDescription(@NonNull Context context, @NonNull View saveUiView,
            @NonNull ValueFinder valueFinder, @NonNull SaveInfo info) {
        final CustomDescription customDescription = info.getCustomDescription();
        if (customDescription == null) {
            return false;
        }
        final int type = info.getType();
        writeLog(MetricsEvent.AUTOFILL_SAVE_CUSTOM_DESCRIPTION, type);

        final RemoteViews template = customDescription.getPresentation();
        if (template == null) {
            Slog.w(TAG, "No remote view on custom description");
            return false;
        }

        // First apply the unconditional transformations (if any) to the templates.
        final ArrayList<Pair<Integer, InternalTransformation>> transformations =
                customDescription.getTransformations();
        if (sVerbose) {
            Slog.v(TAG, "applyCustomDescription(): transformations = " + transformations);
        }
        if (transformations != null) {
            if (!InternalTransformation.batchApply(valueFinder, template, transformations)) {
                Slog.w(TAG, "could not apply main transformations on custom description");
                return false;
            }
        }

        final RemoteViews.OnClickHandler handler = (view, pendingIntent, response) -> {
            Intent intent = response.getLaunchOptions(view).first;
            final LogMaker log =
                    newLogMaker(MetricsEvent.AUTOFILL_SAVE_LINK_TAPPED, type);
            // We need to hide the Save UI before launching the pending intent, and
            // restore back it once the activity is finished, and that's achieved by
            // adding a custom extra in the activity intent.
            final boolean isValid = isValidLink(pendingIntent, intent);
            if (!isValid) {
                log.setType(MetricsEvent.TYPE_UNKNOWN);
                mMetricsLogger.write(log);
                return false;
            }
            if (sVerbose) Slog.v(TAG, "Intercepting custom description intent");
            final IBinder token = mPendingUi.getToken();
            intent.putExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN, token);
            try {
                mPendingUi.client.startIntentSender(pendingIntent.getIntentSender(),
                        intent);
                mPendingUi.setState(PendingUi.STATE_PENDING);
                if (sDebug) Slog.d(TAG, "hiding UI until restored with token " + token);
                hide();
                log.setType(MetricsEvent.TYPE_OPEN);
                mMetricsLogger.write(log);
                return true;
            } catch (RemoteException e) {
                Slog.w(TAG, "error triggering pending intent: " + intent);
                log.setType(MetricsEvent.TYPE_FAILURE);
                mMetricsLogger.write(log);
                return false;
            }
        };

        try {
            // Create the remote view peer.
            final View customSubtitleView = template.applyWithTheme(
                    context, null, handler, mThemeId);

            // Apply batch updates (if any).
            final ArrayList<Pair<InternalValidator, BatchUpdates>> updates =
                    customDescription.getUpdates();
            if (sVerbose) {
                Slog.v(TAG, "applyCustomDescription(): view = " + customSubtitleView
                        + " updates=" + updates);
            }
            if (updates != null) {
                final int size = updates.size();
                if (sDebug) Slog.d(TAG, "custom description has " + size + " batch updates");
                for (int i = 0; i < size; i++) {
                    final Pair<InternalValidator, BatchUpdates> pair = updates.get(i);
                    final InternalValidator condition = pair.first;
                    if (condition == null || !condition.isValid(valueFinder)) {
                        if (sDebug) Slog.d(TAG, "Skipping batch update #" + i );
                        continue;
                    }
                    final BatchUpdates batchUpdates = pair.second;
                    // First apply the updates...
                    final RemoteViews templateUpdates = batchUpdates.getUpdates();
                    if (templateUpdates != null) {
                        if (sDebug) Slog.d(TAG, "Applying template updates for batch update #" + i);
                        templateUpdates.reapply(context, customSubtitleView);
                    }
                    // Then the transformations...
                    final ArrayList<Pair<Integer, InternalTransformation>> batchTransformations =
                            batchUpdates.getTransformations();
                    if (batchTransformations != null) {
                        if (sDebug) {
                            Slog.d(TAG, "Applying child transformation for batch update #" + i
                                    + ": " + batchTransformations);
                        }
                        if (!InternalTransformation.batchApply(valueFinder, template,
                                batchTransformations)) {
                            Slog.w(TAG, "Could not apply child transformation for batch update "
                                    + "#" + i + ": " + batchTransformations);
                            return false;
                        }
                        template.reapply(context, customSubtitleView);
                    }
                }
            }

            // Apply click actions (if any).
            final SparseArray<InternalOnClickAction> actions = customDescription.getActions();
            if (actions != null) {
                final int size = actions.size();
                if (sDebug) Slog.d(TAG, "custom description has " + size + " actions");
                if (!(customSubtitleView instanceof ViewGroup)) {
                    Slog.w(TAG, "cannot apply actions because custom description root is not a "
                            + "ViewGroup: " + customSubtitleView);
                } else {
                    final ViewGroup rootView = (ViewGroup) customSubtitleView;
                    for (int i = 0; i < size; i++) {
                        final int id = actions.keyAt(i);
                        final InternalOnClickAction action = actions.valueAt(i);
                        final View child = rootView.findViewById(id);
                        if (child == null) {
                            Slog.w(TAG, "Ignoring action " + action + " for view " + id
                                    + " because it's not on " + rootView);
                            continue;
                        }
                        child.setOnClickListener((v) -> {
                            if (sVerbose) {
                                Slog.v(TAG, "Applying " + action + " after " + v + " was clicked");
                            }
                            action.onClick(rootView);
                        });
                    }
                }
            }

            // Finally, add the custom description to the save UI.
            final ViewGroup subtitleContainer =
                    saveUiView.findViewById(R.id.autofill_save_custom_subtitle);
            subtitleContainer.addView(customSubtitleView);
            subtitleContainer.setVisibility(View.VISIBLE);
            return true;
        } catch (Exception e) {
            Slog.e(TAG, "Error applying custom description. ", e);
        }
        return false;
    }

    private void setServiceIcon(Context context, View view, Drawable serviceIcon) {
        final ImageView iconView = view.findViewById(R.id.autofill_save_icon);
        final Resources res = context.getResources();

        final int maxWidth = res.getDimensionPixelSize(R.dimen.autofill_save_icon_max_size);
        final int maxHeight = maxWidth;
        final int actualWidth = serviceIcon.getMinimumWidth();
        final int actualHeight = serviceIcon.getMinimumHeight();

        if (actualWidth <= maxWidth && actualHeight <= maxHeight) {
            if (sDebug) {
                Slog.d(TAG, "Adding service icon "
                        + "(" + actualWidth + "x" + actualHeight + ") as it's less than maximum "
                        + "(" + maxWidth + "x" + maxHeight + ").");
            }
            iconView.setImageDrawable(serviceIcon);
        } else {
            Slog.w(TAG, "Not adding service icon of size "
                    + "(" + actualWidth + "x" + actualHeight + ") because maximum is "
                    + "(" + maxWidth + "x" + maxHeight + ").");
            ((ViewGroup)iconView.getParent()).removeView(iconView);
        }
    }

    private static boolean isValidLink(PendingIntent pendingIntent, Intent intent) {
        if (pendingIntent == null) {
            Slog.w(TAG, "isValidLink(): custom description without pending intent");
            return false;
        }
        if (!pendingIntent.isActivity()) {
            Slog.w(TAG, "isValidLink(): pending intent not for activity");
            return false;
        }
        if (intent == null) {
            Slog.w(TAG, "isValidLink(): no intent");
            return false;
        }
        return true;
    }

    private LogMaker newLogMaker(int category, int saveType) {
        return newLogMaker(category).addTaggedData(MetricsEvent.FIELD_AUTOFILL_SAVE_TYPE, saveType);
    }

    private LogMaker newLogMaker(int category) {
        return Helper.newLogMaker(category, mComponentName, mServicePackageName,
                mPendingUi.sessionId, mCompatMode);
    }

    private void writeLog(int category, int saveType) {
        mMetricsLogger.write(newLogMaker(category, saveType));
    }

    /**
     * Update the pending UI, if any.
     *
     * @param operation how to update it.
     * @param token token associated with the pending UI - if it doesn't match the pending token,
     * the operation will be ignored.
     */
    void onPendingUi(int operation, @NonNull IBinder token) {
        if (!mPendingUi.matches(token)) {
            Slog.w(TAG, "restore(" + operation + "): got token " + token + " instead of "
                    + mPendingUi.getToken());
            return;
        }
        final LogMaker log = newLogMaker(MetricsEvent.AUTOFILL_PENDING_SAVE_UI_OPERATION);
        try {
            switch (operation) {
                case AutofillManager.PENDING_UI_OPERATION_RESTORE:
                    if (sDebug) Slog.d(TAG, "Restoring save dialog for " + token);
                    log.setType(MetricsEvent.TYPE_OPEN);
                    show();
                    break;
                case AutofillManager.PENDING_UI_OPERATION_CANCEL:
                    log.setType(MetricsEvent.TYPE_DISMISS);
                    if (sDebug) Slog.d(TAG, "Cancelling pending save dialog for " + token);
                    hide();
                    break;
                default:
                    log.setType(MetricsEvent.TYPE_FAILURE);
                    Slog.w(TAG, "restore(): invalid operation " + operation);
            }
        } finally {
            mMetricsLogger.write(log);
        }
        mPendingUi.setState(PendingUi.STATE_FINISHED);
    }

    private void show() {
        Slog.i(TAG, "Showing save dialog: " + mTitle);
        mDialog.show();
        mOverlayControl.hideOverlays();
   }

    PendingUi hide() {
        if (sVerbose) Slog.v(TAG, "Hiding save dialog.");
        try {
            mDialog.hide();
        } finally {
            mOverlayControl.showOverlays();
        }
        return mPendingUi;
    }

    void destroy() {
        try {
            if (sDebug) Slog.d(TAG, "destroy()");
            throwIfDestroyed();
            mListener.onDestroy();
            mHandler.removeCallbacksAndMessages(mListener);
            mDialog.dismiss();
            mDestroyed = true;
        } finally {
            mOverlayControl.showOverlays();
        }
    }

    private void throwIfDestroyed() {
        if (mDestroyed) {
            throw new IllegalStateException("cannot interact with a destroyed instance");
        }
    }

    @Override
    public String toString() {
        return mTitle == null ? "NO TITLE" : mTitle.toString();
    }

    void dump(PrintWriter pw, String prefix) {
        pw.print(prefix); pw.print("title: "); pw.println(mTitle);
        pw.print(prefix); pw.print("subtitle: "); pw.println(mSubTitle);
        pw.print(prefix); pw.print("pendingUi: "); pw.println(mPendingUi);
        pw.print(prefix); pw.print("service: "); pw.println(mServicePackageName);
        pw.print(prefix); pw.print("app: "); pw.println(mComponentName.toShortString());
        pw.print(prefix); pw.print("compat mode: "); pw.println(mCompatMode);
        pw.print(prefix); pw.print("theme id: "); pw.print(mThemeId);
        switch (mThemeId) {
            case THEME_ID_DARK:
                pw.println(" (dark)");
                break;
            case THEME_ID_LIGHT:
                pw.println(" (light)");
                break;
            default:
                pw.println("(UNKNOWN_MODE)");
                break;
        }
        final View view = mDialog.getWindow().getDecorView();
        final int[] loc = view.getLocationOnScreen();
        pw.print(prefix); pw.print("coordinates: ");
            pw.print('('); pw.print(loc[0]); pw.print(','); pw.print(loc[1]);pw.print(')');
            pw.print('(');
                pw.print(loc[0] + view.getWidth()); pw.print(',');
                pw.print(loc[1] + view.getHeight());pw.println(')');
        pw.print(prefix); pw.print("destroyed: "); pw.println(mDestroyed);
    }
}
