/*
 * 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.statusbar;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;

import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.ActivityManager;
import android.app.Notification;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;

import androidx.test.filters.SmallTest;

import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.coordinator.RemoteInputCoordinator;
import com.android.systemui.statusbar.notification.collection.notifcollection.InternalNotifUpdater;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class SmartReplyControllerTest extends SysuiTestCase {
    private static final String TEST_PACKAGE_NAME = "test";
    private static final int TEST_UID = 0;
    private static final String TEST_CHOICE_TEXT = "A Reply";
    private static final int TEST_CHOICE_INDEX = 2;
    private static final int TEST_CHOICE_COUNT = 4;
    private static final int TEST_ACTION_COUNT = 3;

    private NotificationEntry mEntry;
    private SmartReplyController mSmartReplyController;

    @Mock private NotificationVisibilityProvider mVisibilityProvider;
    @Mock private StatusBarNotification mSbn;
    @Mock private IStatusBarService mIStatusBarService;
    @Mock private NotificationClickNotifier mClickNotifier;
    @Mock private InternalNotifUpdater mInternalNotifUpdater;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mSmartReplyController = new SmartReplyController(
                mock(DumpManager.class),
                mVisibilityProvider,
                mIStatusBarService,
                mClickNotifier);
        RemoteInputCoordinator remoteInputCoordinator = new RemoteInputCoordinator(
                mock(DumpManager.class),
                new RemoteInputNotificationRebuilder(mContext),
                mock(NotificationRemoteInputManager.class),
                mock(Handler.class),
                mSmartReplyController);
        remoteInputCoordinator.setRemoteInputController(mock(RemoteInputController.class));
        NotifPipeline notifPipeline = mock(NotifPipeline.class);
        when(notifPipeline.getInternalNotifUpdater(anyString())).thenReturn(mInternalNotifUpdater);
        remoteInputCoordinator.attach(notifPipeline);

        Notification notification = new Notification.Builder(mContext, "")
                .setSmallIcon(R.drawable.ic_person)
                .setContentTitle("Title")
                .setContentText("Text").build();
        mSbn = new StatusBarNotification(
                TEST_PACKAGE_NAME,
                TEST_PACKAGE_NAME,
                0,
                null,
                TEST_UID,
                0,
                notification,
                new UserHandle(ActivityManager.getCurrentUser()),
                null,
                0);
        mEntry = new NotificationEntryBuilder()
                .setSbn(mSbn)
                .build();
    }

    @Test
    public void testSendSmartReply_updatesRemoteInput() {
        mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
                MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);

        // Sending smart reply should update the notification with reply and spinner.
        verify(mInternalNotifUpdater).onInternalNotificationUpdate(
                argThat(sbn -> sbn.getKey().equals(mSbn.getKey())), anyString());
    }

    @Test
    public void testSendSmartReply_logsToStatusBar() throws RemoteException {
        mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
                MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);

        // Check we log the result to the status bar service.
        verify(mIStatusBarService).onNotificationSmartReplySent(mSbn.getKey(),
                TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, MetricsEvent.LOCATION_UNKNOWN, false);
    }


    @Test
    public void testSendSmartReply_logsToStatusBar_modifiedBeforeSending() throws RemoteException {
        mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
                MetricsEvent.LOCATION_UNKNOWN, true /* modifiedBeforeSending */);

        // Check we log the result to the status bar service.
        verify(mIStatusBarService).onNotificationSmartReplySent(mSbn.getKey(),
                TEST_CHOICE_INDEX, TEST_CHOICE_TEXT, MetricsEvent.LOCATION_UNKNOWN, true);
    }

    @Test
    public void testShowSmartSuggestions_logsToStatusBar() throws RemoteException {
        final boolean generatedByAsssistant = true;
        final boolean editBeforeSending = true;
        mSmartReplyController.smartSuggestionsAdded(mEntry, TEST_CHOICE_COUNT, TEST_ACTION_COUNT,
                generatedByAsssistant, editBeforeSending);

        // Check we log the result to the status bar service.
        verify(mIStatusBarService).onNotificationSmartSuggestionsAdded(mSbn.getKey(),
                TEST_CHOICE_COUNT, TEST_ACTION_COUNT, generatedByAsssistant, editBeforeSending);
    }

    @Test
    public void testSendSmartReply_reportsSending() {
        mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
                MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);

        assertTrue(mSmartReplyController.isSendingSmartReply(mSbn.getKey()));
    }

    @Test
    public void testSendingSmartReply_afterRemove_shouldReturnFalse() {
        mSmartReplyController.smartReplySent(mEntry, TEST_CHOICE_INDEX, TEST_CHOICE_TEXT,
                MetricsEvent.LOCATION_UNKNOWN, false /* modifiedBeforeSending */);
        mSmartReplyController.stopSending(mEntry);

        assertFalse(mSmartReplyController.isSendingSmartReply(mSbn.getKey()));
    }
}
