/*
 * Copyright (C) 2020 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.statusbar.notification.row;

import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
import static android.provider.Settings.Global.NOTIFICATION_BUBBLES;

import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.NotificationChannelHelper;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;

import java.lang.annotation.Retention;

import javax.inject.Provider;

/**
 * The guts of a conversation notification revealed when performing a long press.
 */
public class NotificationConversationInfo extends LinearLayout implements
        NotificationGuts.GutsContent {
    private static final String TAG = "ConversationGuts";


    private INotificationManager mINotificationManager;
    private ShortcutManager mShortcutManager;
    private PackageManager mPm;
    private ConversationIconFactory mIconFactory;
    private VisualStabilityManager mVisualStabilityManager;
    private Handler mMainHandler;
    private Handler mBgHandler;
    private BubbleController mBubbleController;
    private String mPackageName;
    private String mAppName;
    private int mAppUid;
    private String mDelegatePkg;
    private NotificationChannel mNotificationChannel;
    private ShortcutInfo mShortcutInfo;
    private NotificationEntry mEntry;
    private StatusBarNotification mSbn;
    @Nullable private Notification.BubbleMetadata mBubbleMetadata;
    private Context mUserContext;
    private Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
    private boolean mIsDeviceProvisioned;
    private int mAppBubble;

    private TextView mPriorityDescriptionView;
    private TextView mDefaultDescriptionView;
    private TextView mSilentDescriptionView;

    private @Action int mSelectedAction = -1;
    private boolean mPressedApply;

    private OnSnoozeClickListener mOnSnoozeClickListener;
    private OnSettingsClickListener mOnSettingsClickListener;
    private NotificationGuts mGutsContainer;
    private OnConversationSettingsClickListener mOnConversationSettingsClickListener;

    @VisibleForTesting
    boolean mSkipPost = false;
    private int mActualHeight;

    @Retention(SOURCE)
    @IntDef({ACTION_DEFAULT, ACTION_HOME, ACTION_FAVORITE, ACTION_SNOOZE, ACTION_MUTE,
            ACTION_SETTINGS})
    private @interface Action {}
    static final int ACTION_DEFAULT = 0;
    static final int ACTION_HOME = 1;
    static final int ACTION_FAVORITE = 2;
    static final int ACTION_SNOOZE = 3;
    static final int ACTION_MUTE = 4;
    static final int ACTION_SETTINGS = 5;

    // TODO: b/152050825
    /*
    private OnClickListener mOnHomeClick = v -> {
        mSelectedAction = ACTION_HOME;
        mShortcutManager.requestPinShortcut(mShortcutInfo, null);
        mShadeController.animateCollapsePanels();
        mGutsContainer.closeControls(v, true);
    };

    private OnClickListener mOnSnoozeClick = v -> {
        mSelectedAction = ACTION_SNOOZE;
        mOnSnoozeClickListener.onClick(v, 1);
        mGutsContainer.closeControls(v, true);
    };
    */

    private OnClickListener mOnFavoriteClick = v -> {
        setSelectedAction(ACTION_FAVORITE);
        updateToggleActions(mSelectedAction, true);
    };

    private OnClickListener mOnDefaultClick = v -> {
        setSelectedAction(ACTION_DEFAULT);
        updateToggleActions(mSelectedAction, true);
    };

    private OnClickListener mOnMuteClick = v -> {
        setSelectedAction(ACTION_MUTE);
        updateToggleActions(mSelectedAction, true);
    };

    private OnClickListener mOnDone = v -> {
        mPressedApply = true;
        // If the user selected Priority, maybe show the priority onboarding
        if (mSelectedAction == ACTION_FAVORITE && shouldShowPriorityOnboarding()) {
            showPriorityOnboarding();
        }
        mGutsContainer.closeControls(v, true);
    };

    public NotificationConversationInfo(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public interface OnSettingsClickListener {
        void onClick(View v, NotificationChannel channel, int appUid);
    }

    public interface OnConversationSettingsClickListener {
        void onClick();
    }

    public interface OnAppSettingsClickListener {
        void onClick(View v, Intent intent);
    }

    public interface OnSnoozeClickListener {
        void onClick(View v, int hoursToSnooze);
    }

    @VisibleForTesting
    void setSelectedAction(int selectedAction) {
        if (mSelectedAction == selectedAction) {
            return;
        }

        mSelectedAction = selectedAction;
    }

    public void bindNotification(
            ShortcutManager shortcutManager,
            PackageManager pm,
            INotificationManager iNotificationManager,
            VisualStabilityManager visualStabilityManager,
            String pkg,
            NotificationChannel notificationChannel,
            NotificationEntry entry,
            Notification.BubbleMetadata bubbleMetadata,
            OnSettingsClickListener onSettingsClick,
            OnSnoozeClickListener onSnoozeClickListener,
            ConversationIconFactory conversationIconFactory,
            Context userContext,
            Provider<PriorityOnboardingDialogController.Builder> builderProvider,
            boolean isDeviceProvisioned,
            @Main Handler mainHandler,
            @Background Handler bgHandler,
            OnConversationSettingsClickListener onConversationSettingsClickListener,
            BubbleController bubbleController) {
        mSelectedAction = -1;
        mINotificationManager = iNotificationManager;
        mVisualStabilityManager = visualStabilityManager;
        mPackageName = pkg;
        mEntry = entry;
        mSbn = entry.getSbn();
        mPm = pm;
        mAppName = mPackageName;
        mOnSettingsClickListener = onSettingsClick;
        mNotificationChannel = notificationChannel;
        mAppUid = mSbn.getUid();
        mDelegatePkg = mSbn.getOpPkg();
        mIsDeviceProvisioned = isDeviceProvisioned;
        mOnSnoozeClickListener = onSnoozeClickListener;
        mOnConversationSettingsClickListener = onConversationSettingsClickListener;
        mIconFactory = conversationIconFactory;
        mUserContext = userContext;
        mBubbleMetadata = bubbleMetadata;
        mBubbleController = bubbleController;
        mBuilderProvider = builderProvider;
        mMainHandler = mainHandler;
        mBgHandler = bgHandler;
        mShortcutManager = shortcutManager;
        mShortcutInfo = entry.getRanking().getShortcutInfo();
        if (mShortcutInfo == null) {
            throw new IllegalArgumentException("Does not have required information");
        }

        mNotificationChannel = NotificationChannelHelper.createConversationChannelIfNeeded(
                getContext(), mINotificationManager, entry, mNotificationChannel);

        try {
            mAppBubble = mINotificationManager.getBubblePreferenceForPackage(mPackageName, mAppUid);
        } catch (RemoteException e) {
            Log.e(TAG, "can't reach OS", e);
            mAppBubble = BUBBLE_PREFERENCE_SELECTED;
        }

        bindHeader();
        bindActions();

        View done = findViewById(R.id.done);
        done.setOnClickListener(mOnDone);
        done.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate());
    }

    private void bindActions() {

        // TODO: b/152050825
        /*
        Button home = findViewById(R.id.home);
        home.setOnClickListener(mOnHomeClick);
        home.setVisibility(mShortcutInfo != null
                && mShortcutManager.isRequestPinShortcutSupported()
                ? VISIBLE : GONE);

        Button snooze = findViewById(R.id.snooze);
        snooze.setOnClickListener(mOnSnoozeClick);
        */

        if (mAppBubble == BUBBLE_PREFERENCE_ALL) {
            ((TextView) findViewById(R.id.default_summary)).setText(getResources().getString(
                    R.string.notification_channel_summary_default_with_bubbles, mAppName));
        }

        findViewById(R.id.priority).setOnClickListener(mOnFavoriteClick);
        findViewById(R.id.default_behavior).setOnClickListener(mOnDefaultClick);
        findViewById(R.id.silence).setOnClickListener(mOnMuteClick);

        final View settingsButton = findViewById(R.id.info);
        settingsButton.setOnClickListener(getSettingsOnClickListener());
        settingsButton.setVisibility(settingsButton.hasOnClickListeners() ? VISIBLE : GONE);

        updateToggleActions(getSelectedAction(), false);
    }

    private void bindHeader() {
        bindConversationDetails();

        // Delegate
        bindDelegate();
    }

    private OnClickListener getSettingsOnClickListener() {
        if (mAppUid >= 0 && mOnSettingsClickListener != null && mIsDeviceProvisioned) {
            final int appUidF = mAppUid;
            return ((View view) -> {
                mOnSettingsClickListener.onClick(view, mNotificationChannel, appUidF);
            });
        }
        return null;
    }

    private void bindConversationDetails() {
        final TextView channelName = findViewById(R.id.parent_channel_name);
        channelName.setText(mNotificationChannel.getName());

        bindGroup();
        // TODO: bring back when channel name does not include name
        // bindName();
        bindPackage();
        bindIcon(mNotificationChannel.isImportantConversation());
    }

    private void bindIcon(boolean important) {
        ImageView image = findViewById(R.id.conversation_icon);
        image.setImageDrawable(mIconFactory.getConversationDrawable(
                mShortcutInfo, mPackageName, mAppUid, important));
    }

    private void bindPackage() {
        ApplicationInfo info;
        try {
            info = mPm.getApplicationInfo(
                    mPackageName,
                    PackageManager.MATCH_UNINSTALLED_PACKAGES
                            | PackageManager.MATCH_DISABLED_COMPONENTS
                            | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                            | PackageManager.MATCH_DIRECT_BOOT_AWARE);
            if (info != null) {
                mAppName = String.valueOf(mPm.getApplicationLabel(info));
            }
        } catch (PackageManager.NameNotFoundException e) {
        }
        ((TextView) findViewById(R.id.pkg_name)).setText(mAppName);
    }

    private void bindDelegate() {
        TextView delegateView = findViewById(R.id.delegate_name);

        if (!TextUtils.equals(mPackageName, mDelegatePkg)) {
            // this notification was posted by a delegate!
            delegateView.setVisibility(View.VISIBLE);
        } else {
            delegateView.setVisibility(View.GONE);
        }
    }

    private void bindGroup() {
        // Set group information if this channel has an associated group.
        CharSequence groupName = null;
        if (mNotificationChannel != null && mNotificationChannel.getGroup() != null) {
            try {
                final NotificationChannelGroup notificationChannelGroup =
                        mINotificationManager.getNotificationChannelGroupForPackage(
                                mNotificationChannel.getGroup(), mPackageName, mAppUid);
                if (notificationChannelGroup != null) {
                    groupName = notificationChannelGroup.getName();
                }
            } catch (RemoteException e) {
            }
        }
        TextView groupNameView = findViewById(R.id.group_name);
        if (groupName != null) {
            groupNameView.setText(groupName);
            groupNameView.setVisibility(VISIBLE);
        } else {
            groupNameView.setVisibility(GONE);
        }
    }

    @Override
    public boolean post(Runnable action) {
        if (mSkipPost) {
            action.run();
            return true;
        } else {
            return super.post(action);
        }
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mPriorityDescriptionView = findViewById(R.id.priority_summary);
        mDefaultDescriptionView = findViewById(R.id.default_summary);
        mSilentDescriptionView = findViewById(R.id.silence_summary);
    }

    @Override
    public void onFinishedClosing() {
        // TODO: do we need to do anything here?
    }

    @Override
    public boolean needsFalsingProtection() {
        return true;
    }

    @Override
    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
        super.onInitializeAccessibilityEvent(event);
        if (mGutsContainer != null &&
                event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            if (mGutsContainer.isExposed()) {
                event.getText().add(mContext.getString(
                        R.string.notification_channel_controls_opened_accessibility, mAppName));
            } else {
                event.getText().add(mContext.getString(
                        R.string.notification_channel_controls_closed_accessibility, mAppName));
            }
        }
    }

    private void updateToggleActions(int selectedAction, boolean userTriggered) {
        if (userTriggered) {
            TransitionSet transition = new TransitionSet();
            transition.setOrdering(TransitionSet.ORDERING_TOGETHER);
            transition.addTransition(new Fade(Fade.OUT))
                    .addTransition(new ChangeBounds())
                    .addTransition(
                            new Fade(Fade.IN)
                                    .setStartDelay(150)
                                    .setDuration(200)
                                    .setInterpolator(FAST_OUT_SLOW_IN));
            transition.setDuration(350);
            transition.setInterpolator(FAST_OUT_SLOW_IN);
            TransitionManager.beginDelayedTransition(this, transition);
        }

        View priority = findViewById(R.id.priority);
        View defaultBehavior = findViewById(R.id.default_behavior);
        View silence = findViewById(R.id.silence);

        switch (selectedAction) {
            case ACTION_FAVORITE:
                mPriorityDescriptionView.setVisibility(VISIBLE);
                mDefaultDescriptionView.setVisibility(GONE);
                mSilentDescriptionView.setVisibility(GONE);
                post(() -> {
                    priority.setSelected(true);
                    defaultBehavior.setSelected(false);
                    silence.setSelected(false);
                });
                break;

            case ACTION_MUTE:
                mSilentDescriptionView.setVisibility(VISIBLE);
                mDefaultDescriptionView.setVisibility(GONE);
                mPriorityDescriptionView.setVisibility(GONE);
                post(() -> {
                    priority.setSelected(false);
                    defaultBehavior.setSelected(false);
                    silence.setSelected(true);
                });
                break;

            case ACTION_DEFAULT:
                mDefaultDescriptionView.setVisibility(VISIBLE);
                mSilentDescriptionView.setVisibility(GONE);
                mPriorityDescriptionView.setVisibility(GONE);
                post(() -> {
                    priority.setSelected(false);
                    defaultBehavior.setSelected(true);
                    silence.setSelected(false);
                });
                break;

            default:
                throw new IllegalArgumentException("Unrecognized behavior: " + mSelectedAction);
        }

        boolean isAChange = getSelectedAction() != selectedAction;
        TextView done = findViewById(R.id.done);
        done.setText(isAChange
                ? R.string.inline_ok_button
                : R.string.inline_done_button);

        // update icon in case importance has changed
        bindIcon(selectedAction == ACTION_FAVORITE);
    }

    int getSelectedAction() {
        if (mNotificationChannel.getImportance() <= IMPORTANCE_LOW
                && mNotificationChannel.getImportance() > IMPORTANCE_UNSPECIFIED) {
            return ACTION_MUTE;
        } else {
            if (mNotificationChannel.isImportantConversation()) {
                return ACTION_FAVORITE;
            }
        }
        return ACTION_DEFAULT;
    }

    private void updateChannel() {
        mBgHandler.post(
                new UpdateChannelRunnable(mINotificationManager, mPackageName,
                        mAppUid, mSelectedAction, mNotificationChannel));
        mEntry.markForUserTriggeredMovement(true);
        mMainHandler.postDelayed(
                mVisualStabilityManager::temporarilyAllowReordering,
                StackStateAnimator.ANIMATION_DURATION_STANDARD);
    }

    private boolean shouldShowPriorityOnboarding() {
        return !Prefs.getBoolean(mUserContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING, false);
    }

    private void showPriorityOnboarding() {
        View onboardingView = LayoutInflater.from(mContext)
                .inflate(R.layout.priority_onboarding_half_shell, null);

        boolean ignoreDnd = false;
        try {
            ignoreDnd = mINotificationManager
                    .getConsolidatedNotificationPolicy().priorityConversationSenders ==
                    NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
        } catch (RemoteException e) {
            Log.e(TAG, "Could not check conversation senders", e);
        }

        boolean showAsBubble = mBubbleMetadata != null
                && mBubbleMetadata.getAutoExpandBubble()
                && Settings.Global.getInt(mContext.getContentResolver(),
                        NOTIFICATION_BUBBLES, 0) == 1;

        PriorityOnboardingDialogController controller = mBuilderProvider.get()
                .setContext(mUserContext)
                .setView(onboardingView)
                .setIgnoresDnd(ignoreDnd)
                .setShowsAsBubble(showAsBubble)
                .setIcon(mIconFactory.getBaseIconDrawable(mShortcutInfo))
                .setBadge(mIconFactory.getAppBadge(
                        mPackageName, UserHandle.getUserId(mSbn.getUid())))
                .setOnSettingsClick(mOnConversationSettingsClickListener)
                .build();

        controller.init();
        controller.show();
    }

    @Override
    public void setGutsParent(NotificationGuts guts) {
        mGutsContainer = guts;
    }

    @Override
    public boolean willBeRemoved() {
        return false;
    }

    @Override
    public boolean shouldBeSaved() {
        return mPressedApply;
    }

    @Override
    public View getContentView() {
        return this;
    }

    @Override
    public boolean handleCloseControls(boolean save, boolean force) {
        if (save && mSelectedAction > -1) {
            updateChannel();
        }
        return false;
    }

    @Override
    public int getActualHeight() {
        // Because we're animating the bounds, getHeight will return the small height at the
        // beginning of the animation. Instead we'd want it to already return the end value
        return mActualHeight;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mActualHeight = getHeight();
    }

    @VisibleForTesting
    public boolean isAnimating() {
        return false;
    }

    class UpdateChannelRunnable implements Runnable {

        private final INotificationManager mINotificationManager;
        private final String mAppPkg;
        private final int mAppUid;
        private  NotificationChannel mChannelToUpdate;
        private final @Action int mAction;

        public UpdateChannelRunnable(INotificationManager notificationManager,
                String packageName, int appUid, @Action int action,
                @NonNull NotificationChannel channelToUpdate) {
            mINotificationManager = notificationManager;
            mAppPkg = packageName;
            mAppUid = appUid;
            mChannelToUpdate = channelToUpdate;
            mAction = action;
        }

        @Override
        public void run() {
            try {
                switch (mAction) {
                    case ACTION_FAVORITE:
                        mChannelToUpdate.setImportantConversation(true);
                        if (mChannelToUpdate.isImportantConversation()) {
                            mChannelToUpdate.setAllowBubbles(true);
                            if (mAppBubble == BUBBLE_PREFERENCE_NONE) {
                                mINotificationManager.setBubblesAllowed(mAppPkg, mAppUid,
                                        BUBBLE_PREFERENCE_SELECTED);
                            }
                            post(() -> {
                                mBubbleController.onUserChangedImportance(mEntry);
                            });
                        }
                        mChannelToUpdate.setImportance(Math.max(
                                mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
                        break;
                    case ACTION_DEFAULT:
                        mChannelToUpdate.setImportance(Math.max(
                                mChannelToUpdate.getOriginalImportance(), IMPORTANCE_DEFAULT));
                        if (mChannelToUpdate.isImportantConversation()) {
                            mChannelToUpdate.setImportantConversation(false);
                            mChannelToUpdate.setAllowBubbles(false);
                        }
                        break;
                    case ACTION_MUTE:
                        if (mChannelToUpdate.getImportance() == IMPORTANCE_UNSPECIFIED
                                || mChannelToUpdate.getImportance() >= IMPORTANCE_DEFAULT) {
                            mChannelToUpdate.setImportance(IMPORTANCE_LOW);
                        }
                        if (mChannelToUpdate.isImportantConversation()) {
                            mChannelToUpdate.setImportantConversation(false);
                            mChannelToUpdate.setAllowBubbles(false);
                        }
                        break;
                }

                mINotificationManager.updateNotificationChannelForPackage(
                            mAppPkg, mAppUid, mChannelToUpdate);
            } catch (RemoteException e) {
                Log.e(TAG, "Unable to update notification channel", e);
            }
        }
    }
}
