/*
 * Copyright (C) 2008 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 android.app.cts;

import static org.mockito.Mockito.*;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Instrumentation;
import android.app.stubs.DialogStubActivity;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.database.Cursor;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteDatabase;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.MediumTest;
import android.widget.ListView;

import androidx.test.InstrumentationRegistry;

import com.android.compatibility.common.util.PollingCheck;

import java.io.File;

@MediumTest
public class AlertDialog_BuilderCursorTest
        extends ActivityInstrumentationTestCase2<DialogStubActivity> {
    private Builder mBuilder;
    private Context mContext;
    private Instrumentation mInstrumentation;
    private AlertDialog mDialog;
    private ListView mListView;

    private static final String TEXT_COLUMN_NAME = "text";
    private static final String CHECKED_COLUMN_NAME = "checked";

    private String[] mTextContent;
    private boolean[] mCheckedContent;

    private String[] mProjectionWithChecked;
    private String[] mProjectionWithoutChecked;

    private SQLiteDatabase mDatabase;
    private File mDatabaseFile;
    private Cursor mCursor;

    private OnClickListener mOnClickListener = mock(OnClickListener.class);

    /**
     * Multi-choice click listener that is registered on our {@link AlertDialog} when it's in
     * multi-choide mode. Note that this needs to be a separate class that is also protected (not
     * private) so that Mockito can "spy" on it.
     */
    protected class MultiChoiceClickListener implements OnMultiChoiceClickListener {
        private boolean[] mCheckedTracker;

        public MultiChoiceClickListener(boolean[] checkedTracker) {
            mCheckedTracker = checkedTracker;
        }

        @Override
        public void onClick(DialogInterface dialog, int which,
                boolean isChecked) {
            // Update the underlying database with the new checked
            // state for the specific row
            mCursor.moveToPosition(which);
            ContentValues valuesToUpdate = new ContentValues();
            valuesToUpdate.put(CHECKED_COLUMN_NAME, isChecked ? 1 : 0);
            mDatabase.update("test", valuesToUpdate,
                    TEXT_COLUMN_NAME + " = ?",
                    new String[] { mCursor.getString(1) } );
            mCursor.requery();
            mCheckedTracker[which] = isChecked;
        }
    }

    public AlertDialog_BuilderCursorTest() {
        super("android.app.stubs", DialogStubActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mBuilder = null;
        mInstrumentation = getInstrumentation();
        mContext = getActivity();

        PollingCheck.waitFor(() -> getActivity().hasWindowFocus());

        mListView = null;
        mDialog = null;

        // Local test data for the tests
        mTextContent = new String[] { "Adele", "Beyonce", "Ciara", "Dido" };
        mCheckedContent = new boolean[] { false, false, true, false };

        // Two projections - one with "checked" column and one without
        mProjectionWithChecked = new String[] {
                "_id",                       // 0
                TEXT_COLUMN_NAME,            // 1
                CHECKED_COLUMN_NAME          // 2
        };
        mProjectionWithoutChecked = new String[] {
                "_id",                       // 0
                TEXT_COLUMN_NAME             // 1
        };

        File dbDir = mContext.getDir("tests", Context.MODE_PRIVATE);
        mDatabaseFile = new File(dbDir, "database_alert_dialog_test.db");
        if (mDatabaseFile.exists()) {
            mDatabaseFile.delete();
        }
        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
        assertNotNull(mDatabase);
        // Create and populate a test table
        mDatabase.execSQL(
                "CREATE TABLE test (_id INTEGER PRIMARY KEY, " + TEXT_COLUMN_NAME +
                        " TEXT, " + CHECKED_COLUMN_NAME + " INTEGER);");
        for (int i = 0; i < mTextContent.length; i++) {
            mDatabase.execSQL("INSERT INTO test (" + TEXT_COLUMN_NAME + ", " +
                    CHECKED_COLUMN_NAME + ") VALUES ('" + mTextContent[i] + "', " +
                    (mCheckedContent[i] ? "1" : "0") + ");");
        }
    }

    @Override
    protected void tearDown() throws Exception {
        if (mCursor != null) {
            // Close the cursor on the UI thread as the list view in the alert dialog
            // will get notified of any change to the underlying cursor.
            InstrumentationRegistry.getInstrumentation().runOnMainSync(
                    () -> {
                        mCursor.close();
                        mCursor = null;
                    });
        }
        if (mDatabase != null) {
            mDatabase.close();
        }
        if (mDatabaseFile != null) {
            mDatabaseFile.delete();
        }

        super.tearDown();
    }

    public void testSetCursor() throws Throwable {
        // Use a projection without "checked" column
        mCursor = mDatabase.query("test", mProjectionWithoutChecked,
                null, null, null, null, null);
        assertNotNull(mCursor);

        runTestOnUiThread(
                () -> {
                    mBuilder = new Builder(mContext);
                    mBuilder.setCursor(mCursor, mOnClickListener, TEXT_COLUMN_NAME);
                    mDialog = mBuilder.show();
                    mListView = mDialog.getListView();
                    mListView.performItemClick(null, 0, 0);
                });
        mInstrumentation.waitForIdleSync();
        final SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
        assertEquals(mCursor.getString(1), selected.getString(1));
        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
        verifyNoMoreInteractions(mOnClickListener);
    }

    public void testSetSingleChoiceItemsWithParamCursor() throws Throwable {
        // Use a projection without "checked" column
        mCursor = mDatabase.query("test", mProjectionWithoutChecked,
                null, null, null, null, null);
        assertNotNull(mCursor);

        runTestOnUiThread(
                () -> {
                    mBuilder = new Builder(mContext);
                    mBuilder.setSingleChoiceItems(mCursor, 0, TEXT_COLUMN_NAME, mOnClickListener);
                    mDialog = mBuilder.show();
                    mListView = mDialog.getListView();
                    mListView.performItemClick(null, 0, 0);
                });
        mInstrumentation.waitForIdleSync();
        final SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
        assertEquals(mCursor.getString(1), selected.getString(1));
        verify(mOnClickListener, times(1)).onClick(mDialog, 0);
        verifyNoMoreInteractions(mOnClickListener);
    }

    public void testSetMultiChoiceItemsWithParamCursor() throws Throwable {
        mCursor = mDatabase.query("test", mProjectionWithChecked,
                null, null, null, null, null);
        assertNotNull(mCursor);

        final boolean[] checkedTracker = mCheckedContent.clone();
        final OnMultiChoiceClickListener mockMultiChoiceClickListener =
                spy(new MultiChoiceClickListener(checkedTracker));
        runTestOnUiThread(
                () -> {
                    mBuilder = new Builder(mContext);
                    mBuilder.setMultiChoiceItems(mCursor, CHECKED_COLUMN_NAME, TEXT_COLUMN_NAME,
                            mockMultiChoiceClickListener);
                    mDialog = mBuilder.show();
                    mListView = mDialog.getListView();
                    mListView.performItemClick(null, 0, 0);
                });
        mInstrumentation.waitForIdleSync();

        SQLiteCursor selected = (SQLiteCursor) mListView.getSelectedItem();
        assertEquals(mCursor.getString(0), selected.getString(0));
        verify(mockMultiChoiceClickListener, times(1)).onClick(mDialog, 0, true);
        // Verify that our multi-choice listener was invoked to update our tracker array
        assertTrue(checkedTracker[0]);
        assertFalse(checkedTracker[1]);
        assertTrue(checkedTracker[2]);
        assertFalse(checkedTracker[3]);

        runTestOnUiThread(() -> mListView.performItemClick(null, 1, 1));
        mInstrumentation.waitForIdleSync();

        selected = (SQLiteCursor) mListView.getSelectedItem();
        assertEquals(mCursor.getString(1), selected.getString(1));
        verify(mockMultiChoiceClickListener, times(1)).onClick(mDialog, 1, true);
        // Verify that our multi-choice listener was invoked to update our tracker array
        assertTrue(checkedTracker[0]);
        assertTrue(checkedTracker[1]);
        assertTrue(checkedTracker[2]);
        assertFalse(checkedTracker[3]);

        verifyNoMoreInteractions(mockMultiChoiceClickListener);
    }
}
