package com.android.systemui.statusbar.policy;

import android.annotation.ColorInt;
import android.annotation.NonNull;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.InsetDrawable;
import android.graphics.drawable.RippleDrawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Layout;
import android.text.TextPaint;
import android.text.method.TransformationMethod;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.widget.Button;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ContrastColorUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.SmartReplyController;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;

import java.text.BreakIterator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;

/** View which displays smart reply and smart actions buttons in notifications. */
public class SmartReplyView extends ViewGroup {

    private static final String TAG = "SmartReplyView";

    private static final int MEASURE_SPEC_ANY_LENGTH =
            MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

    private static final Comparator<View> DECREASING_MEASURED_WIDTH_WITHOUT_PADDING_COMPARATOR =
            (v1, v2) -> ((v2.getMeasuredWidth() - v2.getPaddingLeft() - v2.getPaddingRight())
                    - (v1.getMeasuredWidth() - v1.getPaddingLeft() - v1.getPaddingRight()));

    private static final int SQUEEZE_FAILED = -1;

    private final SmartReplyConstants mConstants;
    private final KeyguardDismissUtil mKeyguardDismissUtil;
    private final NotificationRemoteInputManager mRemoteInputManager;

    /**
     * The upper bound for the height of this view in pixels. Notifications are automatically
     * recreated on density or font size changes so caching this should be fine.
     */
    private final int mHeightUpperLimit;

    /** Spacing to be applied between views. */
    private final int mSpacing;

    /** Horizontal padding of smart reply buttons if all of them use only one line of text. */
    private final int mSingleLineButtonPaddingHorizontal;

    /** Horizontal padding of smart reply buttons if at least one of them uses two lines of text. */
    private final int mDoubleLineButtonPaddingHorizontal;

    /** Increase in width of a smart reply button as a result of using two lines instead of one. */
    private final int mSingleToDoubleLineButtonWidthIncrease;

    private final BreakIterator mBreakIterator;

    private PriorityQueue<Button> mCandidateButtonQueueForSqueezing;

    private View mSmartReplyContainer;

    /**
     * Whether the smart replies in this view were generated by the notification assistant. If not
     * they're provided by the app.
     */
    private boolean mSmartRepliesGeneratedByAssistant = false;

    @ColorInt
    private int mCurrentBackgroundColor;
    @ColorInt
    private final int mDefaultBackgroundColor;
    @ColorInt
    private final int mDefaultStrokeColor;
    @ColorInt
    private final int mDefaultTextColor;
    @ColorInt
    private final int mDefaultTextColorDarkBg;
    @ColorInt
    private final int mRippleColorDarkBg;
    @ColorInt
    private final int mRippleColor;
    private final int mStrokeWidth;
    private final double mMinStrokeContrast;

    private ActivityStarter mActivityStarter;

    public SmartReplyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mConstants = Dependency.get(SmartReplyConstants.class);
        mKeyguardDismissUtil = Dependency.get(KeyguardDismissUtil.class);
        mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);

        mHeightUpperLimit = NotificationUtils.getFontScaledHeight(mContext,
            R.dimen.smart_reply_button_max_height);

        mCurrentBackgroundColor = context.getColor(R.color.smart_reply_button_background);
        mDefaultBackgroundColor = mCurrentBackgroundColor;
        mDefaultTextColor = mContext.getColor(R.color.smart_reply_button_text);
        mDefaultTextColorDarkBg = mContext.getColor(R.color.smart_reply_button_text_dark_bg);
        mDefaultStrokeColor = mContext.getColor(R.color.smart_reply_button_stroke);
        mRippleColor = mContext.getColor(R.color.notification_ripple_untinted_color);
        mRippleColorDarkBg = Color.argb(Color.alpha(mRippleColor),
                255 /* red */, 255 /* green */, 255 /* blue */);
        mMinStrokeContrast = ContrastColorUtil.calculateContrast(mDefaultStrokeColor,
                mDefaultBackgroundColor);

        int spacing = 0;
        int singleLineButtonPaddingHorizontal = 0;
        int doubleLineButtonPaddingHorizontal = 0;
        int strokeWidth = 0;

        final TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.SmartReplyView,
                0, 0);
        final int length = arr.getIndexCount();
        for (int i = 0; i < length; i++) {
            int attr = arr.getIndex(i);
            if (attr == R.styleable.SmartReplyView_spacing) {
                spacing = arr.getDimensionPixelSize(i, 0);
            } else if (attr == R.styleable.SmartReplyView_singleLineButtonPaddingHorizontal) {
                singleLineButtonPaddingHorizontal = arr.getDimensionPixelSize(i, 0);
            } else if (attr == R.styleable.SmartReplyView_doubleLineButtonPaddingHorizontal) {
                doubleLineButtonPaddingHorizontal = arr.getDimensionPixelSize(i, 0);
            } else if (attr == R.styleable.SmartReplyView_buttonStrokeWidth) {
                strokeWidth = arr.getDimensionPixelSize(i, 0);
            }
        }
        arr.recycle();

        mStrokeWidth = strokeWidth;
        mSpacing = spacing;
        mSingleLineButtonPaddingHorizontal = singleLineButtonPaddingHorizontal;
        mDoubleLineButtonPaddingHorizontal = doubleLineButtonPaddingHorizontal;
        mSingleToDoubleLineButtonWidthIncrease =
                2 * (doubleLineButtonPaddingHorizontal - singleLineButtonPaddingHorizontal);


        mBreakIterator = BreakIterator.getLineInstance();
        reallocateCandidateButtonQueueForSqueezing();
    }

    /**
     * Returns an upper bound for the height of this view in pixels. This method is intended to be
     * invoked before onMeasure, so it doesn't do any analysis on the contents of the buttons.
     */
    public int getHeightUpperLimit() {
       return mHeightUpperLimit;
    }

    private void reallocateCandidateButtonQueueForSqueezing() {
        // Instead of clearing the priority queue, we re-allocate so that it would fit all buttons
        // exactly. This avoids (1) wasting memory because PriorityQueue never shrinks and
        // (2) growing in onMeasure.
        // The constructor throws an IllegalArgument exception if initial capacity is less than 1.
        mCandidateButtonQueueForSqueezing = new PriorityQueue<>(
                Math.max(getChildCount(), 1), DECREASING_MEASURED_WIDTH_WITHOUT_PADDING_COMPARATOR);
    }

    /**
     * Reset the smart suggestions view to allow adding new replies and actions.
     */
    public void resetSmartSuggestions(View newSmartReplyContainer) {
        mSmartReplyContainer = newSmartReplyContainer;
        removeAllViews();
        mCurrentBackgroundColor = mDefaultBackgroundColor;
    }

    /**
     * Add buttons to the {@link SmartReplyView} - these buttons must have been preinflated using
     * one of the methods in this class.
     */
    public void addPreInflatedButtons(List<Button> smartSuggestionButtons) {
        for (Button button : smartSuggestionButtons) {
            addView(button);
        }
        reallocateCandidateButtonQueueForSqueezing();
    }

    /**
     * Add smart replies to this view, using the provided {@link RemoteInput} and
     * {@link PendingIntent} to respond when the user taps a smart reply. Only the replies that fit
     * into the notification are shown.
     */
    public List<Button> inflateRepliesFromRemoteInput(
            @NonNull SmartReplies smartReplies,
            SmartReplyController smartReplyController, NotificationEntry entry,
            boolean delayOnClickListener) {
        List<Button> buttons = new ArrayList<>();

        if (smartReplies.remoteInput != null && smartReplies.pendingIntent != null) {
            if (smartReplies.choices != null) {
                for (int i = 0; i < smartReplies.choices.length; ++i) {
                    buttons.add(inflateReplyButton(
                            this, getContext(), i, smartReplies, smartReplyController, entry,
                            delayOnClickListener));
                }
                this.mSmartRepliesGeneratedByAssistant = smartReplies.fromAssistant;
            }
        }
        return buttons;
    }

    /**
     * Add smart actions to be shown next to smart replies. Only the actions that fit into the
     * notification are shown.
     */
    public List<Button> inflateSmartActions(@NonNull SmartActions smartActions,
            SmartReplyController smartReplyController, NotificationEntry entry,
            HeadsUpManager headsUpManager, boolean delayOnClickListener) {
        List<Button> buttons = new ArrayList<>();
        int numSmartActions = smartActions.actions.size();
        for (int n = 0; n < numSmartActions; n++) {
            Notification.Action action = smartActions.actions.get(n);
            if (action.actionIntent != null) {
                buttons.add(inflateActionButton(
                        this, getContext(), n, smartActions, smartReplyController, entry,
                        headsUpManager, delayOnClickListener));
            }
        }
        return buttons;
    }

    /**
     * Inflate an instance of this class.
     */
    public static SmartReplyView inflate(Context context) {
        return (SmartReplyView) LayoutInflater.from(context).inflate(
                R.layout.smart_reply_view, null /* root */);
    }

    @VisibleForTesting
    static Button inflateReplyButton(SmartReplyView smartReplyView, Context context,
            int replyIndex, SmartReplies smartReplies, SmartReplyController smartReplyController,
            NotificationEntry entry, boolean useDelayedOnClickListener) {
        Button b = (Button) LayoutInflater.from(context).inflate(
                R.layout.smart_reply_button, smartReplyView, false);
        CharSequence choice = smartReplies.choices[replyIndex];
        b.setText(choice);

        OnDismissAction action = () -> {
            if (smartReplyView.mConstants.getEffectiveEditChoicesBeforeSending(
                    smartReplies.remoteInput.getEditChoicesBeforeSending())) {
                EditedSuggestionInfo editedSuggestionInfo =
                        new EditedSuggestionInfo(choice, replyIndex);
                smartReplyView.mRemoteInputManager.activateRemoteInput(b,
                        new RemoteInput[] { smartReplies.remoteInput }, smartReplies.remoteInput,
                        smartReplies.pendingIntent, editedSuggestionInfo);
                return false;
            }

            smartReplyController.smartReplySent(entry, replyIndex, b.getText(),
                    NotificationLogger.getNotificationLocation(entry).toMetricsEventEnum(),
                    false /* modifiedBeforeSending */);
            Bundle results = new Bundle();
            results.putString(smartReplies.remoteInput.getResultKey(), choice.toString());
            Intent intent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
            RemoteInput.addResultsToIntent(new RemoteInput[] { smartReplies.remoteInput }, intent,
                    results);
            RemoteInput.setResultsSource(intent, RemoteInput.SOURCE_CHOICE);
            entry.setHasSentReply();
            try {
                smartReplies.pendingIntent.send(context, 0, intent);
            } catch (PendingIntent.CanceledException e) {
                Log.w(TAG, "Unable to send smart reply", e);
            }
            // Note that as inflateReplyButton is called mSmartReplyContainer is null, but when the
            // reply Button is added to the SmartReplyView mSmartReplyContainer will be set. So, it
            // will not be possible for a user to trigger this on-click-listener without
            // mSmartReplyContainer being set.
            smartReplyView.mSmartReplyContainer.setVisibility(View.GONE);
            return false; // do not defer
        };

        OnClickListener onClickListener = view ->
            smartReplyView.mKeyguardDismissUtil.executeWhenUnlocked(action);
        if (useDelayedOnClickListener) {
            onClickListener = new DelayedOnClickListener(onClickListener,
                    smartReplyView.mConstants.getOnClickInitDelay());
        }
        b.setOnClickListener(onClickListener);

        b.setAccessibilityDelegate(new AccessibilityDelegate() {
            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
                super.onInitializeAccessibilityNodeInfo(host, info);
                String label = smartReplyView.getResources().getString(
                        R.string.accessibility_send_smart_reply);
                info.addAction(new AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, label));
            }
        });

        SmartReplyView.setButtonColors(b, smartReplyView.mCurrentBackgroundColor,
                smartReplyView.mDefaultStrokeColor, smartReplyView.mDefaultTextColor,
                smartReplyView.mRippleColor, smartReplyView.mStrokeWidth);
        return b;
    }

    @VisibleForTesting
    static Button inflateActionButton(SmartReplyView smartReplyView, Context context,
            int actionIndex, SmartActions smartActions,
            SmartReplyController smartReplyController, NotificationEntry entry,
            HeadsUpManager headsUpManager, boolean useDelayedOnClickListener) {
        Notification.Action action = smartActions.actions.get(actionIndex);
        Button button = (Button) LayoutInflater.from(context).inflate(
                R.layout.smart_action_button, smartReplyView, false);
        button.setText(action.title);

        Drawable iconDrawable = action.getIcon().loadDrawable(context);
        // Add the action icon to the Smart Action button.
        int newIconSize = context.getResources().getDimensionPixelSize(
                R.dimen.smart_action_button_icon_size);
        iconDrawable.setBounds(0, 0, newIconSize, newIconSize);
        button.setCompoundDrawables(iconDrawable, null, null, null);

        OnClickListener onClickListener = view ->
                smartReplyView.getActivityStarter().startPendingIntentDismissingKeyguard(
                        action.actionIntent,
                        () -> {
                            smartReplyController.smartActionClicked(
                                    entry, actionIndex, action, smartActions.fromAssistant);
                            headsUpManager.removeNotification(entry.key, true);
                        }, entry.getRow());
        if (useDelayedOnClickListener) {
            onClickListener = new DelayedOnClickListener(onClickListener,
                    smartReplyView.mConstants.getOnClickInitDelay());
        }
        button.setOnClickListener(onClickListener);

        // Mark this as an Action button
        final LayoutParams lp = (LayoutParams) button.getLayoutParams();
        lp.buttonType = SmartButtonType.ACTION;
        return button;
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new LayoutParams(mContext, attrs);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams params) {
        return new LayoutParams(params.width, params.height);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int targetWidth = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.UNSPECIFIED
                ? Integer.MAX_VALUE : MeasureSpec.getSize(widthMeasureSpec);

        // Mark all buttons as hidden and un-squeezed.
        resetButtonsLayoutParams();

        if (!mCandidateButtonQueueForSqueezing.isEmpty()) {
            Log.wtf(TAG, "Single line button queue leaked between onMeasure calls");
            mCandidateButtonQueueForSqueezing.clear();
        }

        SmartSuggestionMeasures accumulatedMeasures = new SmartSuggestionMeasures(
                mPaddingLeft + mPaddingRight,
                0 /* maxChildHeight */,
                mSingleLineButtonPaddingHorizontal);
        int displayedChildCount = 0;

        // Set up a list of suggestions where actions come before replies. Note that the Buttons
        // themselves have already been added to the view hierarchy in an order such that Smart
        // Replies are shown before Smart Actions. The order of the list below determines which
        // suggestions will be shown at all - only the first X elements are shown (where X depends
        // on how much space each suggestion button needs).
        List<View> smartActions = filterActionsOrReplies(SmartButtonType.ACTION);
        List<View> smartReplies = filterActionsOrReplies(SmartButtonType.REPLY);
        List<View> smartSuggestions = new ArrayList<>(smartActions);
        smartSuggestions.addAll(smartReplies);
        List<View> coveredSuggestions = new ArrayList<>();

        // SmartSuggestionMeasures for all action buttons, this will be filled in when the first
        // reply button is added.
        SmartSuggestionMeasures actionsMeasures = null;

        final int maxNumActions = mConstants.getMaxNumActions();
        int numShownActions = 0;

        for (View child : smartSuggestions) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (maxNumActions != -1 // -1 means 'no limit'
                    && lp.buttonType == SmartButtonType.ACTION
                    && numShownActions >= maxNumActions) {
                // We've reached the maximum number of actions, don't add another one!
                continue;
            }

            child.setPadding(accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingTop(),
                    accumulatedMeasures.mButtonPaddingHorizontal, child.getPaddingBottom());
            child.measure(MEASURE_SPEC_ANY_LENGTH, heightMeasureSpec);

            coveredSuggestions.add(child);

            final int lineCount = ((Button) child).getLineCount();
            if (lineCount < 1 || lineCount > 2) {
                // If smart reply has no text, or more than two lines, then don't show it.
                continue;
            }

            if (lineCount == 1) {
                mCandidateButtonQueueForSqueezing.add((Button) child);
            }

            // Remember the current measurements in case the current button doesn't fit in.
            SmartSuggestionMeasures originalMeasures = accumulatedMeasures.clone();
            if (actionsMeasures == null && lp.buttonType == SmartButtonType.REPLY) {
                // We've added all actions (we go through actions first), now add their
                // measurements.
                actionsMeasures = accumulatedMeasures.clone();
            }

            final int spacing = displayedChildCount == 0 ? 0 : mSpacing;
            final int childWidth = child.getMeasuredWidth();
            final int childHeight = child.getMeasuredHeight();
            accumulatedMeasures.mMeasuredWidth += spacing + childWidth;
            accumulatedMeasures.mMaxChildHeight =
                    Math.max(accumulatedMeasures.mMaxChildHeight, childHeight);

            // Do we need to increase the number of lines in smart reply buttons to two?
            final boolean increaseToTwoLines =
                    (accumulatedMeasures.mButtonPaddingHorizontal
                            == mSingleLineButtonPaddingHorizontal)
                    && (lineCount == 2 || accumulatedMeasures.mMeasuredWidth > targetWidth);
            if (increaseToTwoLines) {
                accumulatedMeasures.mMeasuredWidth +=
                        (displayedChildCount + 1) * mSingleToDoubleLineButtonWidthIncrease;
                accumulatedMeasures.mButtonPaddingHorizontal =
                        mDoubleLineButtonPaddingHorizontal;
            }

            // If the last button doesn't fit into the remaining width, try squeezing preceding
            // smart reply buttons.
            if (accumulatedMeasures.mMeasuredWidth > targetWidth) {
                // Keep squeezing preceding and current smart reply buttons until they all fit.
                while (accumulatedMeasures.mMeasuredWidth > targetWidth
                        && !mCandidateButtonQueueForSqueezing.isEmpty()) {
                    final Button candidate = mCandidateButtonQueueForSqueezing.poll();
                    final int squeezeReduction = squeezeButton(candidate, heightMeasureSpec);
                    if (squeezeReduction != SQUEEZE_FAILED) {
                        accumulatedMeasures.mMaxChildHeight =
                                Math.max(accumulatedMeasures.mMaxChildHeight,
                                        candidate.getMeasuredHeight());
                        accumulatedMeasures.mMeasuredWidth -= squeezeReduction;
                    }
                }

                // If the current button still doesn't fit after squeezing all buttons, undo the
                // last squeezing round.
                if (accumulatedMeasures.mMeasuredWidth > targetWidth) {
                    accumulatedMeasures = originalMeasures;

                    // Mark all buttons from the last squeezing round as "failed to squeeze", so
                    // that they're re-measured without squeezing later.
                    markButtonsWithPendingSqueezeStatusAs(
                            LayoutParams.SQUEEZE_STATUS_FAILED, coveredSuggestions);

                    // The current button doesn't fit, keep on adding lower-priority buttons in case
                    // any of those fit.
                    continue;
                }

                // The current button fits, so mark all squeezed buttons as "successfully squeezed"
                // to prevent them from being un-squeezed in a subsequent squeezing round.
                markButtonsWithPendingSqueezeStatusAs(
                        LayoutParams.SQUEEZE_STATUS_SUCCESSFUL, coveredSuggestions);
            }

            lp.show = true;
            displayedChildCount++;
            if (lp.buttonType == SmartButtonType.ACTION) {
                numShownActions++;
            }
        }

        if (mSmartRepliesGeneratedByAssistant) {
            if (!gotEnoughSmartReplies(smartReplies)) {
                // We don't have enough smart replies - hide all of them.
                for (View smartReplyButton : smartReplies) {
                    final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams();
                    lp.show = false;
                }
                // Reset our measures back to when we had only added actions (before adding
                // replies).
                accumulatedMeasures = actionsMeasures;
            }
        }

        // We're done squeezing buttons, so we can clear the priority queue.
        mCandidateButtonQueueForSqueezing.clear();

        // Finally, we need to re-measure some buttons.
        remeasureButtonsIfNecessary(accumulatedMeasures.mButtonPaddingHorizontal,
                                    accumulatedMeasures.mMaxChildHeight);

        int buttonHeight = Math.max(getSuggestedMinimumHeight(), mPaddingTop
                + accumulatedMeasures.mMaxChildHeight + mPaddingBottom);

        // Set the corner radius to half the button height to make the side of the buttons look like
        // a semicircle.
        for (View smartSuggestionButton : smartSuggestions) {
            setCornerRadius((Button) smartSuggestionButton, ((float) buttonHeight) / 2);
        }

        setMeasuredDimension(
                resolveSize(Math.max(getSuggestedMinimumWidth(),
                                     accumulatedMeasures.mMeasuredWidth),
                            widthMeasureSpec),
                resolveSize(buttonHeight, heightMeasureSpec));
    }

    /**
     * Fields we keep track of inside onMeasure() to correctly measure the SmartReplyView depending
     * on which suggestions are added.
     */
    private static class SmartSuggestionMeasures {
        int mMeasuredWidth = -1;
        int mMaxChildHeight = -1;
        int mButtonPaddingHorizontal = -1;

        SmartSuggestionMeasures(int measuredWidth, int maxChildHeight,
                int buttonPaddingHorizontal) {
            this.mMeasuredWidth = measuredWidth;
            this.mMaxChildHeight = maxChildHeight;
            this.mButtonPaddingHorizontal = buttonPaddingHorizontal;
        }

        public SmartSuggestionMeasures clone() {
            return new SmartSuggestionMeasures(
                    mMeasuredWidth, mMaxChildHeight, mButtonPaddingHorizontal);
        }
    }

    /**
     * Returns whether our notification contains at least N smart replies (or 0) where N is
     * determined by {@link SmartReplyConstants}.
     */
    private boolean gotEnoughSmartReplies(List<View> smartReplies) {
        int numShownReplies = 0;
        for (View smartReplyButton : smartReplies) {
            final LayoutParams lp = (LayoutParams) smartReplyButton.getLayoutParams();
            if (lp.show) {
                numShownReplies++;
            }
        }
        if (numShownReplies == 0
                || numShownReplies >= mConstants.getMinNumSystemGeneratedReplies()) {
            // We have enough replies, yay!
            return true;
        }
        return false;
    }

    private List<View> filterActionsOrReplies(SmartButtonType buttonType) {
        List<View> actions = new ArrayList<>();
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (child.getVisibility() != View.VISIBLE || !(child instanceof Button)) {
                continue;
            }
            if (lp.buttonType == buttonType) {
                actions.add(child);
            }
        }
        return actions;
    }

    private void resetButtonsLayoutParams() {
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            lp.show = false;
            lp.squeezeStatus = LayoutParams.SQUEEZE_STATUS_NONE;
        }
    }

    private int squeezeButton(Button button, int heightMeasureSpec) {
        final int estimatedOptimalTextWidth = estimateOptimalSqueezedButtonTextWidth(button);
        if (estimatedOptimalTextWidth == SQUEEZE_FAILED) {
            return SQUEEZE_FAILED;
        }
        return squeezeButtonToTextWidth(button, heightMeasureSpec, estimatedOptimalTextWidth);
    }

    private int estimateOptimalSqueezedButtonTextWidth(Button button) {
        // Find a line-break point in the middle of the smart reply button text.
        final String rawText = button.getText().toString();

        // The button sometimes has a transformation affecting text layout (e.g. all caps).
        final TransformationMethod transformation = button.getTransformationMethod();
        final String text = transformation == null ?
                rawText : transformation.getTransformation(rawText, button).toString();
        final int length = text.length();
        mBreakIterator.setText(text);

        if (mBreakIterator.preceding(length / 2) == BreakIterator.DONE) {
            if (mBreakIterator.next() == BreakIterator.DONE) {
                // Can't find a single possible line break in either direction.
                return SQUEEZE_FAILED;
            }
        }

        final TextPaint paint = button.getPaint();
        final int initialPosition = mBreakIterator.current();
        final float initialLeftTextWidth = Layout.getDesiredWidth(text, 0, initialPosition, paint);
        final float initialRightTextWidth =
                Layout.getDesiredWidth(text, initialPosition, length, paint);
        float optimalTextWidth = Math.max(initialLeftTextWidth, initialRightTextWidth);

        if (initialLeftTextWidth != initialRightTextWidth) {
            // See if there's a better line-break point (leading to a more narrow button) in
            // either left or right direction.
            final boolean moveLeft = initialLeftTextWidth > initialRightTextWidth;
            final int maxSqueezeRemeasureAttempts = mConstants.getMaxSqueezeRemeasureAttempts();
            for (int i = 0; i < maxSqueezeRemeasureAttempts; i++) {
                final int newPosition =
                        moveLeft ? mBreakIterator.previous() : mBreakIterator.next();
                if (newPosition == BreakIterator.DONE) {
                    break;
                }

                final float newLeftTextWidth = Layout.getDesiredWidth(text, 0, newPosition, paint);
                final float newRightTextWidth =
                        Layout.getDesiredWidth(text, newPosition, length, paint);
                final float newOptimalTextWidth = Math.max(newLeftTextWidth, newRightTextWidth);
                if (newOptimalTextWidth < optimalTextWidth) {
                    optimalTextWidth = newOptimalTextWidth;
                } else {
                    break;
                }

                boolean tooFar = moveLeft
                        ? newLeftTextWidth <= newRightTextWidth
                        : newLeftTextWidth >= newRightTextWidth;
                if (tooFar) {
                    break;
                }
            }
        }

        return (int) Math.ceil(optimalTextWidth);
    }

    /**
     * Returns the combined width of the left drawable (the action icon) and the padding between the
     * drawable and the button text.
     */
    private int getLeftCompoundDrawableWidthWithPadding(Button button) {
        Drawable[] drawables = button.getCompoundDrawables();
        Drawable leftDrawable = drawables[0];
        if (leftDrawable == null) return 0;

        return leftDrawable.getBounds().width() + button.getCompoundDrawablePadding();
    }

    private int squeezeButtonToTextWidth(Button button, int heightMeasureSpec, int textWidth) {
        int oldWidth = button.getMeasuredWidth();
        if (button.getPaddingLeft() != mDoubleLineButtonPaddingHorizontal) {
            // Correct for the fact that the button was laid out with single-line horizontal
            // padding.
            oldWidth += mSingleToDoubleLineButtonWidthIncrease;
        }

        // Re-measure the squeezed smart reply button.
        button.setPadding(mDoubleLineButtonPaddingHorizontal, button.getPaddingTop(),
                mDoubleLineButtonPaddingHorizontal, button.getPaddingBottom());
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(
                2 * mDoubleLineButtonPaddingHorizontal + textWidth
                      + getLeftCompoundDrawableWidthWithPadding(button), MeasureSpec.AT_MOST);
        button.measure(widthMeasureSpec, heightMeasureSpec);

        final int newWidth = button.getMeasuredWidth();

        final LayoutParams lp = (LayoutParams) button.getLayoutParams();
        if (button.getLineCount() > 2 || newWidth >= oldWidth) {
            lp.squeezeStatus = LayoutParams.SQUEEZE_STATUS_FAILED;
            return SQUEEZE_FAILED;
        } else {
            lp.squeezeStatus = LayoutParams.SQUEEZE_STATUS_PENDING;
            return oldWidth - newWidth;
        }
    }

    private void remeasureButtonsIfNecessary(
            int buttonPaddingHorizontal, int maxChildHeight) {
        final int maxChildHeightMeasure =
                MeasureSpec.makeMeasureSpec(maxChildHeight, MeasureSpec.EXACTLY);

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (!lp.show) {
                continue;
            }

            boolean requiresNewMeasure = false;
            int newWidth = child.getMeasuredWidth();

            // Re-measure reason 1: The button needs to be un-squeezed (either because it resulted
            // in more than two lines or because it was unnecessary).
            if (lp.squeezeStatus == LayoutParams.SQUEEZE_STATUS_FAILED) {
                requiresNewMeasure = true;
                newWidth = Integer.MAX_VALUE;
            }

            // Re-measure reason 2: The button's horizontal padding is incorrect (because it was
            // measured with the wrong number of lines).
            if (child.getPaddingLeft() != buttonPaddingHorizontal) {
                requiresNewMeasure = true;
                if (newWidth != Integer.MAX_VALUE) {
                    if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) {
                        // Change padding (2->1 line).
                        newWidth -= mSingleToDoubleLineButtonWidthIncrease;
                    } else {
                        // Change padding (1->2 lines).
                        newWidth += mSingleToDoubleLineButtonWidthIncrease;
                    }
                }
                child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(),
                        buttonPaddingHorizontal, child.getPaddingBottom());
            }

            // Re-measure reason 3: The button's height is less than the max height of all buttons
            // (all should have the same height).
            if (child.getMeasuredHeight() != maxChildHeight) {
                requiresNewMeasure = true;
            }

            if (requiresNewMeasure) {
                child.measure(MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.AT_MOST),
                        maxChildHeightMeasure);
            }
        }
    }

    private void markButtonsWithPendingSqueezeStatusAs(
            int squeezeStatus, List<View> coveredChildren) {
        for (View child : coveredChildren) {
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.squeezeStatus == LayoutParams.SQUEEZE_STATUS_PENDING) {
                lp.squeezeStatus = squeezeStatus;
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        final boolean isRtl = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;

        final int width = right - left;
        int position = isRtl ? width - mPaddingRight : mPaddingLeft;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (!lp.show) {
                continue;
            }

            final int childWidth = child.getMeasuredWidth();
            final int childHeight = child.getMeasuredHeight();
            final int childLeft = isRtl ? position - childWidth : position;
            child.layout(childLeft, 0, childLeft + childWidth, childHeight);

            final int childWidthWithSpacing = childWidth + mSpacing;
            if (isRtl) {
                position -= childWidthWithSpacing;
            } else {
                position += childWidthWithSpacing;
            }
        }
    }

    @Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
        return lp.show && super.drawChild(canvas, child, drawingTime);
    }

    public void setBackgroundTintColor(int backgroundColor) {
        if (backgroundColor == mCurrentBackgroundColor) {
            // Same color ignoring.
           return;
        }
        mCurrentBackgroundColor = backgroundColor;

        final boolean dark = !ContrastColorUtil.isColorLight(backgroundColor);

        int textColor = ContrastColorUtil.ensureTextContrast(
                dark ? mDefaultTextColorDarkBg : mDefaultTextColor,
                backgroundColor | 0xff000000, dark);
        int strokeColor = ContrastColorUtil.ensureContrast(
                mDefaultStrokeColor, backgroundColor | 0xff000000, dark, mMinStrokeContrast);
        int rippleColor = dark ? mRippleColorDarkBg : mRippleColor;

        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final Button child = (Button) getChildAt(i);
            setButtonColors(child, backgroundColor, strokeColor, textColor, rippleColor,
                    mStrokeWidth);
        }
    }

    private static void setButtonColors(Button button, int backgroundColor, int strokeColor,
            int textColor, int rippleColor, int strokeWidth) {
        Drawable drawable = button.getBackground();
        if (drawable instanceof RippleDrawable) {
            // Mutate in case other notifications are using this drawable.
            drawable = drawable.mutate();
            RippleDrawable ripple = (RippleDrawable) drawable;
            ripple.setColor(ColorStateList.valueOf(rippleColor));
            Drawable inset = ripple.getDrawable(0);
            if (inset instanceof InsetDrawable) {
                Drawable background = ((InsetDrawable) inset).getDrawable();
                if (background instanceof GradientDrawable) {
                    GradientDrawable gradientDrawable = (GradientDrawable) background;
                    gradientDrawable.setColor(backgroundColor);
                    gradientDrawable.setStroke(strokeWidth, strokeColor);
                }
            }
            button.setBackground(drawable);
        }
        button.setTextColor(textColor);
    }

    private void setCornerRadius(Button button, float radius) {
        Drawable drawable = button.getBackground();
        if (drawable instanceof RippleDrawable) {
            // Mutate in case other notifications are using this drawable.
            drawable = drawable.mutate();
            RippleDrawable ripple = (RippleDrawable) drawable;
            Drawable inset = ripple.getDrawable(0);
            if (inset instanceof InsetDrawable) {
                Drawable background = ((InsetDrawable) inset).getDrawable();
                if (background instanceof GradientDrawable) {
                    GradientDrawable gradientDrawable = (GradientDrawable) background;
                    gradientDrawable.setCornerRadius(radius);
                }
            }
        }
    }

    private ActivityStarter getActivityStarter() {
        if (mActivityStarter == null) {
            mActivityStarter = Dependency.get(ActivityStarter.class);
        }
        return mActivityStarter;
    }

    private enum SmartButtonType {
        REPLY,
        ACTION
    }

    @VisibleForTesting
    static class LayoutParams extends ViewGroup.LayoutParams {

        /** Button is not squeezed. */
        private static final int SQUEEZE_STATUS_NONE = 0;

        /**
         * Button was successfully squeezed, but it might be un-squeezed later if the squeezing
         * turns out to have been unnecessary (because there's still not enough space to add another
         * button).
         */
        private static final int SQUEEZE_STATUS_PENDING = 1;

        /** Button was successfully squeezed and it won't be un-squeezed. */
        private static final int SQUEEZE_STATUS_SUCCESSFUL = 2;

        /**
         * Button wasn't successfully squeezed. The squeezing resulted in more than two lines of
         * text or it didn't reduce the button's width at all. The button will have to be
         * re-measured to use only one line of text.
         */
        private static final int SQUEEZE_STATUS_FAILED = 3;

        private boolean show = false;
        private int squeezeStatus = SQUEEZE_STATUS_NONE;
        private SmartButtonType buttonType = SmartButtonType.REPLY;

        private LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
        }

        private LayoutParams(int width, int height) {
            super(width, height);
        }

        @VisibleForTesting
        boolean isShown() {
            return show;
        }
    }

    /**
     * Data class for smart replies.
     */
    public static class SmartReplies {
        @NonNull
        public final RemoteInput remoteInput;
        @NonNull
        public final PendingIntent pendingIntent;
        @NonNull
        public final CharSequence[] choices;
        public final boolean fromAssistant;

        public SmartReplies(CharSequence[] choices, RemoteInput remoteInput,
                PendingIntent pendingIntent, boolean fromAssistant) {
            this.choices = choices;
            this.remoteInput = remoteInput;
            this.pendingIntent = pendingIntent;
            this.fromAssistant = fromAssistant;
        }
    }


    /**
     * Data class for smart actions.
     */
    public static class SmartActions {
        @NonNull
        public final List<Notification.Action> actions;
        public final boolean fromAssistant;

        public SmartActions(List<Notification.Action> actions, boolean fromAssistant) {
            this.actions = actions;
            this.fromAssistant = fromAssistant;
        }
    }

    /**
     * An OnClickListener wrapper that blocks the underlying OnClickListener for a given amount of
     * time.
     */
    private static class DelayedOnClickListener implements OnClickListener {
        private final OnClickListener mActualListener;
        private final long mInitDelayMs;
        private final long mInitTimeMs;

        DelayedOnClickListener(OnClickListener actualOnClickListener, long initDelayMs) {
            mActualListener = actualOnClickListener;
            mInitDelayMs = initDelayMs;
            mInitTimeMs = SystemClock.elapsedRealtime();
        }

        public void onClick(View v) {
            if (hasFinishedInitialization()) {
                mActualListener.onClick(v);
            } else {
                Log.i(TAG, "Accidental Smart Suggestion click registered, delay: " + mInitDelayMs);
            }
        }

        private boolean hasFinishedInitialization() {
            return SystemClock.elapsedRealtime() >= mInitTimeMs + mInitDelayMs;
        }
    }
}
