/*
 * Copyright (C) 2018 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.systemui.biometrics;

import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricPrompt;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.UserManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.util.leak.RotationUtils;

/**
 * Abstract base class. Shows a dialog for BiometricPrompt.
 */
public abstract class BiometricDialogView extends LinearLayout {

    private static final String TAG = "BiometricDialogView";

    private static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
    private static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
    private static final String KEY_STATE = "key_state";
    private static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
    private static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
    private static final String KEY_ERROR_TEXT_IS_TEMPORARY = "key_error_text_is_temporary";
    private static final String KEY_ERROR_TEXT_COLOR = "key_error_text_color";

    private static final int ANIMATION_DURATION_SHOW = 250; // ms
    private static final int ANIMATION_DURATION_AWAY = 350; // ms

    protected static final int MSG_RESET_MESSAGE = 1;

    protected static final int STATE_IDLE = 0;
    protected static final int STATE_AUTHENTICATING = 1;
    protected static final int STATE_ERROR = 2;
    protected static final int STATE_PENDING_CONFIRMATION = 3;
    protected static final int STATE_AUTHENTICATED = 4;

    private final IBinder mWindowToken = new Binder();
    private final Interpolator mLinearOutSlowIn;
    private final WindowManager mWindowManager;
    private final UserManager mUserManager;
    private final DevicePolicyManager mDevicePolicyManager;
    private final float mAnimationTranslationOffset;
    private final int mErrorColor;
    private final float mDialogWidth;
    protected final DialogViewCallback mCallback;

    protected final ViewGroup mLayout;
    protected final LinearLayout mDialog;
    protected final TextView mTitleText;
    protected final TextView mSubtitleText;
    protected final TextView mDescriptionText;
    protected final ImageView mBiometricIcon;
    protected final TextView mErrorText;
    protected final Button mPositiveButton;
    protected final Button mNegativeButton;
    protected final Button mTryAgainButton;

    protected final int mTextColor;

    private Bundle mBundle;
    private Bundle mRestoredState;

    private int mState = STATE_IDLE;
    private boolean mAnimatingAway;
    private boolean mWasForceRemoved;
    private boolean mSkipIntro;
    protected boolean mRequireConfirmation;
    private int mUserId; // used to determine if we should show work background

    protected abstract int getHintStringResourceId();
    protected abstract int getAuthenticatedAccessibilityResourceId();
    protected abstract int getIconDescriptionResourceId();
    protected abstract int getDelayAfterAuthenticatedDurationMs();
    protected abstract boolean shouldGrayAreaDismissDialog();
    protected abstract void handleResetMessage();
    protected abstract void updateIcon(int oldState, int newState);

    private final Runnable mShowAnimationRunnable = new Runnable() {
        @Override
        public void run() {
            mLayout.animate()
                    .alpha(1f)
                    .setDuration(ANIMATION_DURATION_SHOW)
                    .setInterpolator(mLinearOutSlowIn)
                    .withLayer()
                    .start();
            mDialog.animate()
                    .translationY(0)
                    .setDuration(ANIMATION_DURATION_SHOW)
                    .setInterpolator(mLinearOutSlowIn)
                    .withLayer()
                    .withEndAction(() -> onDialogAnimatedIn())
                    .start();
        }
    };

    protected Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_RESET_MESSAGE:
                    handleResetMessage();
                    break;
                default:
                    Log.e(TAG, "Unhandled message: " + msg.what);
                    break;
            }
        }
    };

    public BiometricDialogView(Context context, DialogViewCallback callback) {
        super(context);
        mCallback = callback;
        mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
        mWindowManager = mContext.getSystemService(WindowManager.class);
        mUserManager = mContext.getSystemService(UserManager.class);
        mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
        mAnimationTranslationOffset = getResources()
                .getDimension(R.dimen.biometric_dialog_animation_translation_offset);
        mErrorColor = getResources().getColor(R.color.biometric_dialog_error);
        mTextColor = getResources().getColor(R.color.biometric_dialog_gray);

        DisplayMetrics metrics = new DisplayMetrics();
        mWindowManager.getDefaultDisplay().getMetrics(metrics);
        mDialogWidth = Math.min(metrics.widthPixels, metrics.heightPixels);

        // Create the dialog
        LayoutInflater factory = LayoutInflater.from(getContext());
        mLayout = (ViewGroup) factory.inflate(R.layout.biometric_dialog, this, false);
        addView(mLayout);

        mLayout.setOnKeyListener(new View.OnKeyListener() {
            boolean downPressed = false;
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (keyCode != KeyEvent.KEYCODE_BACK) {
                    return false;
                }
                if (event.getAction() == KeyEvent.ACTION_DOWN && downPressed == false) {
                    downPressed = true;
                } else if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    downPressed = false;
                } else if (event.getAction() == KeyEvent.ACTION_UP && downPressed == true) {
                    downPressed = false;
                    mCallback.onUserCanceled();
                }
                return true;
            }
        });

        final View space = mLayout.findViewById(R.id.space);
        final View leftSpace = mLayout.findViewById(R.id.left_space);
        final View rightSpace = mLayout.findViewById(R.id.right_space);

        mDialog = mLayout.findViewById(R.id.dialog);
        mTitleText = mLayout.findViewById(R.id.title);
        mSubtitleText = mLayout.findViewById(R.id.subtitle);
        mDescriptionText = mLayout.findViewById(R.id.description);
        mBiometricIcon = mLayout.findViewById(R.id.biometric_icon);
        mErrorText = mLayout.findViewById(R.id.error);
        mNegativeButton = mLayout.findViewById(R.id.button2);
        mPositiveButton = mLayout.findViewById(R.id.button1);
        mTryAgainButton = mLayout.findViewById(R.id.button_try_again);

        mBiometricIcon.setContentDescription(
                getResources().getString(getIconDescriptionResourceId()));

        setDismissesDialog(space);
        setDismissesDialog(leftSpace);
        setDismissesDialog(rightSpace);

        mNegativeButton.setOnClickListener((View v) -> {
            if (mState == STATE_PENDING_CONFIRMATION || mState == STATE_AUTHENTICATED) {
                mCallback.onUserCanceled();
            } else {
                mCallback.onNegativePressed();
            }
        });

        mPositiveButton.setOnClickListener((View v) -> {
            updateState(STATE_AUTHENTICATED);
            mHandler.postDelayed(() -> {
                mCallback.onPositivePressed();
            }, getDelayAfterAuthenticatedDurationMs());
        });

        mTryAgainButton.setOnClickListener((View v) -> {
            handleResetMessage();
            updateState(STATE_AUTHENTICATING);
            showTryAgainButton(false /* show */);
            mCallback.onTryAgainPressed();
        });

        // Must set these in order for the back button events to be received.
        mLayout.setFocusableInTouchMode(true);
        mLayout.requestFocus();
    }

    public void onSaveState(Bundle bundle) {
        bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
        bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
        bundle.putInt(KEY_STATE, mState);
        bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
        bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
        bundle.putBoolean(KEY_ERROR_TEXT_IS_TEMPORARY, mHandler.hasMessages(MSG_RESET_MESSAGE));
        bundle.putInt(KEY_ERROR_TEXT_COLOR, mErrorText.getCurrentTextColor());
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        final ImageView backgroundView = mLayout.findViewById(R.id.background);

        if (mUserManager.isManagedProfile(mUserId)) {
            final Drawable image = getResources().getDrawable(R.drawable.work_challenge_background,
                    mContext.getTheme());
            image.setColorFilter(mDevicePolicyManager.getOrganizationColorForUser(mUserId),
                    PorterDuff.Mode.DARKEN);
            backgroundView.setImageDrawable(image);
        } else {
            backgroundView.setImageDrawable(null);
            backgroundView.setBackgroundColor(R.color.biometric_dialog_dim_color);
        }

        mNegativeButton.setVisibility(View.VISIBLE);

        if (RotationUtils.getRotation(mContext) != RotationUtils.ROTATION_NONE) {
            mDialog.getLayoutParams().width = (int) mDialogWidth;
        }

        if (mRestoredState == null) {
            updateState(STATE_AUTHENTICATING);
            mErrorText.setText(getHintStringResourceId());
            mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
            mErrorText.setVisibility(View.VISIBLE);
        } else {
            updateState(mState);
        }

        CharSequence titleText = mBundle.getCharSequence(BiometricPrompt.KEY_TITLE);

        mTitleText.setVisibility(View.VISIBLE);
        mTitleText.setText(titleText);

        final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
        if (TextUtils.isEmpty(subtitleText)) {
            mSubtitleText.setVisibility(View.GONE);
        } else {
            mSubtitleText.setVisibility(View.VISIBLE);
            mSubtitleText.setText(subtitleText);
        }

        final CharSequence descriptionText =
                mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
        if (TextUtils.isEmpty(descriptionText)) {
            mDescriptionText.setVisibility(View.GONE);
        } else {
            mDescriptionText.setVisibility(View.VISIBLE);
            mDescriptionText.setText(descriptionText);
        }

        mNegativeButton.setText(mBundle.getCharSequence(BiometricPrompt.KEY_NEGATIVE_TEXT));

        if (requiresConfirmation() && mRestoredState == null) {
            mPositiveButton.setVisibility(View.VISIBLE);
            mPositiveButton.setEnabled(false);
        }

        if (mWasForceRemoved || mSkipIntro) {
            // Show the dialog immediately
            mLayout.animate().cancel();
            mDialog.animate().cancel();
            mDialog.setAlpha(1.0f);
            mDialog.setTranslationY(0);
            mLayout.setAlpha(1.0f);
        } else {
            // Dim the background and slide the dialog up
            mDialog.setTranslationY(mAnimationTranslationOffset);
            mLayout.setAlpha(0f);
            postOnAnimation(mShowAnimationRunnable);
        }
        mWasForceRemoved = false;
        mSkipIntro = false;
    }

    private void setDismissesDialog(View v) {
        v.setClickable(true);
        v.setOnClickListener(v1 -> {
            if (mState != STATE_AUTHENTICATED && shouldGrayAreaDismissDialog()) {
                mCallback.onUserCanceled();
            }
        });
    }

    public void startDismiss() {
        mAnimatingAway = true;

        // This is where final cleanup should occur.
        final Runnable endActionRunnable = new Runnable() {
            @Override
            public void run() {
                mWindowManager.removeView(BiometricDialogView.this);
                mAnimatingAway = false;
                // Set the icons / text back to normal state
                handleResetMessage();
                showTryAgainButton(false /* show */);
                updateState(STATE_IDLE);
            }
        };

        postOnAnimation(new Runnable() {
            @Override
            public void run() {
                mLayout.animate()
                        .alpha(0f)
                        .setDuration(ANIMATION_DURATION_AWAY)
                        .setInterpolator(mLinearOutSlowIn)
                        .withLayer()
                        .start();
                mDialog.animate()
                        .translationY(mAnimationTranslationOffset)
                        .setDuration(ANIMATION_DURATION_AWAY)
                        .setInterpolator(mLinearOutSlowIn)
                        .withLayer()
                        .withEndAction(endActionRunnable)
                        .start();
            }
        });
    }

    /**
     * Force remove the window, cancelling any animation that's happening. This should only be
     * called if we want to quickly show the dialog again (e.g. on rotation). Calling this method
     * will cause the dialog to show without an animation the next time it's attached.
     */
    public void forceRemove() {
        mLayout.animate().cancel();
        mDialog.animate().cancel();
        mWindowManager.removeView(BiometricDialogView.this);
        mAnimatingAway = false;
        mWasForceRemoved = true;
    }

    /**
     * Skip the intro animation
     */
    public void setSkipIntro(boolean skip) {
        mSkipIntro = skip;
    }

    public boolean isAnimatingAway() {
        return mAnimatingAway;
    }

    public void setBundle(Bundle bundle) {
        mBundle = bundle;
    }

    public void setRequireConfirmation(boolean requireConfirmation) {
        mRequireConfirmation = requireConfirmation;
    }

    public boolean requiresConfirmation() {
        return mRequireConfirmation;
    }

    public void setUserId(int userId) {
        mUserId = userId;
    }

    public ViewGroup getLayout() {
        return mLayout;
    }

    // Shows an error/help message
    protected void showTemporaryMessage(String message) {
        mHandler.removeMessages(MSG_RESET_MESSAGE);
        mErrorText.setText(message);
        mErrorText.setTextColor(mErrorColor);
        mErrorText.setContentDescription(message);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                BiometricPrompt.HIDE_DIALOG_DELAY);
    }

    /**
     * Transient help message (acquire) is received, dialog stays showing. Sensor stays in
     * "authenticating" state.
     * @param message
     */
    public void onHelpReceived(String message) {
        updateState(STATE_ERROR);
        showTemporaryMessage(message);
    }

    public void onAuthenticationFailed(String message) {
        updateState(STATE_ERROR);
        showTemporaryMessage(message);
    }

    /**
     * Hard error is received, dialog will be dismissed soon.
     * @param error
     */
    public void onErrorReceived(String error) {
        updateState(STATE_ERROR);
        showTemporaryMessage(error);
        showTryAgainButton(false /* show */);
        mCallback.onErrorShown(); // TODO: Split between fp and face
    }

    public void updateState(int newState) {
        if (newState == STATE_PENDING_CONFIRMATION) {
            mHandler.removeMessages(MSG_RESET_MESSAGE);
            mErrorText.setVisibility(View.INVISIBLE);
            mPositiveButton.setVisibility(View.VISIBLE);
            mPositiveButton.setEnabled(true);
        } else if (newState == STATE_AUTHENTICATED) {
            mPositiveButton.setVisibility(View.GONE);
            mNegativeButton.setVisibility(View.GONE);
            mErrorText.setVisibility(View.INVISIBLE);
        }

        if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
            mNegativeButton.setText(R.string.cancel);
        }

        updateIcon(mState, newState);
        mState = newState;
    }

    public void showTryAgainButton(boolean show) {
    }

    public void onDialogAnimatedIn() {
    }

    public void restoreState(Bundle bundle) {
        mRestoredState = bundle;
        mTryAgainButton.setVisibility(bundle.getInt(KEY_TRY_AGAIN_VISIBILITY));
        mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
        mState = bundle.getInt(KEY_STATE);
        mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
        mErrorText.setContentDescription(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
        mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
        mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));

        if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
                    BiometricPrompt.HIDE_DIALOG_DELAY);
        }
    }

    protected int getState() {
        return mState;
    }

    public WindowManager.LayoutParams getLayoutParams() {
        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                PixelFormat.TRANSLUCENT);
        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
        lp.setTitle("BiometricDialogView");
        lp.token = mWindowToken;
        return lp;
    }
}
