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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.app.Activity;
import android.content.Context;
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.View;
import android.view.autofill.AutofillValue;
import android.widget.DatePicker;

import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.MediumTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * Test {@link DatePicker}.
 */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class DatePickerTest {
    private Activity mActivity;
    private DatePicker mDatePickerSpinnerMode;
    private DatePicker mDatePickerCalendarMode;

    @Rule
    public ActivityTestRule<DatePickerCtsActivity> mActivityRule =
            new ActivityTestRule<>(DatePickerCtsActivity.class);

    @Before
    public void setUp() {
        mActivity = mActivityRule.getActivity();
        mDatePickerSpinnerMode = (DatePicker) mActivity.findViewById(R.id.date_picker_spinner_mode);
        mDatePickerCalendarMode =
                (DatePicker) mActivity.findViewById(R.id.date_picker_calendar_mode);
    }

    @Test
    public void testConstructor() {
        new DatePicker(mActivity);

        new DatePicker(mActivity, null);

        new DatePicker(mActivity, null, android.R.attr.datePickerStyle);

        new DatePicker(mActivity, null, 0, android.R.style.Widget_DeviceDefault_DatePicker);

        new DatePicker(mActivity, null, 0, android.R.style.Widget_Material_DatePicker);

        new DatePicker(mActivity, null, 0, android.R.style.Widget_Material_Light_DatePicker);
    }

    @UiThreadTest
    @Test
    public void testSetEnabled() {
        verifySetEnabled(mDatePickerSpinnerMode);
        verifySetEnabled(mDatePickerCalendarMode);
    }

    private void verifySetEnabled(DatePicker datePicker) {
        assertTrue(datePicker.isEnabled());

        datePicker.setEnabled(false);
        assertFalse(datePicker.isEnabled());
        assertNull(datePicker.getAutofillValue());
        assertEquals(View.AUTOFILL_TYPE_NONE, datePicker.getAutofillType());

        datePicker.setEnabled(true);
        assertTrue(datePicker.isEnabled());
        assertNotNull(datePicker.getAutofillValue());
        assertEquals(View.AUTOFILL_TYPE_DATE, datePicker.getAutofillType());
    }

    private void verifyInit(DatePicker datePicker) {
        final DatePicker.OnDateChangedListener mockDateChangeListener =
                mock(DatePicker.OnDateChangedListener.class);

        datePicker.init(2000, 10, 15, mockDateChangeListener);
        assertValues(datePicker, 2000, 10, 15);

        verifyZeroInteractions(mockDateChangeListener);
    }

    @UiThreadTest
    @Test
    public void testInit() {
        verifyInit(mDatePickerSpinnerMode);
        verifyInit(mDatePickerCalendarMode);
    }

    private void verifyAccessDate(DatePicker datePicker) {
        final DatePicker.OnDateChangedListener mockDateChangeListener =
                mock(DatePicker.OnDateChangedListener.class);

        datePicker.init(2000, 10, 15, mockDateChangeListener);
        assertValues(datePicker, 2000, 10, 15);
        verify(mockDateChangeListener, never()).onDateChanged(any(DatePicker.class), anyInt(),
                anyInt(), anyInt());

        datePicker.updateDate(1989, 9, 19);
        assertValues(datePicker, 1989, 9, 19);
        verify(mockDateChangeListener, times(1)).onDateChanged(datePicker, 1989, 9, 19);

        verifyNoMoreInteractions(mockDateChangeListener);
    }

    @UiThreadTest
    @Test
    public void testAccessDate() {
        verifyAccessDate(mDatePickerSpinnerMode);
        verifyAccessDate(mDatePickerCalendarMode);
    }

    private void verifySetOnDateChangedListener(DatePicker datePicker) {
        final DatePicker.OnDateChangedListener mockDateChangeListener1 =
                mock(DatePicker.OnDateChangedListener.class);
        final DatePicker.OnDateChangedListener mockDateChangeListener2 =
                mock(DatePicker.OnDateChangedListener.class);

        datePicker.init(2000, 10, 15, mockDateChangeListener1);
        datePicker.updateDate(1989, 9, 19);
        assertValues(datePicker, 1989, 9, 19);
        verify(mockDateChangeListener1, times(1)).onDateChanged(datePicker, 1989, 9, 19);
        verify(mockDateChangeListener2, times(0)).onDateChanged(datePicker, 1989, 9, 19);

        datePicker.setOnDateChangedListener(mockDateChangeListener2);
        datePicker.updateDate(2000, 10, 15);
        assertValues(datePicker, 2000, 10, 15);
        verify(mockDateChangeListener1, times(0)).onDateChanged(datePicker, 2000, 10, 15);
        verify(mockDateChangeListener2, times(1)).onDateChanged(datePicker, 2000, 10, 15);
    }

    @UiThreadTest
    @Test
    public void testSetOnDateChangedListener() {
        verifySetOnDateChangedListener(mDatePickerSpinnerMode);
        verifySetOnDateChangedListener(mDatePickerCalendarMode);
    }

    private void verifyUpdateDate(DatePicker datePicker) {
        datePicker.updateDate(1989, 9, 19);
        assertValues(datePicker, 1989, 9, 19);
    }

    @UiThreadTest
    @Test
    public void testUpdateDate() {
        verifyUpdateDate(mDatePickerSpinnerMode);
        verifyUpdateDate(mDatePickerCalendarMode);
    }

    private void verifyMinMaxDate(DatePicker datePicker) {
        // Use a range of minus/plus one year as min/max dates
        final Calendar minCalendar = new GregorianCalendar();
        minCalendar.set(Calendar.YEAR, minCalendar.get(Calendar.YEAR) - 1);
        final Calendar maxCalendar = new GregorianCalendar();
        maxCalendar.set(Calendar.YEAR, maxCalendar.get(Calendar.YEAR) + 1);

        final long minDate = minCalendar.getTime().getTime();
        final long maxDate = maxCalendar.getTime().getTime();

        datePicker.setMinDate(minDate);
        datePicker.setMaxDate(maxDate);

        assertEquals(datePicker.getMinDate(), minDate);
        assertEquals(datePicker.getMaxDate(), maxDate);
    }

    @UiThreadTest
    @Test
    public void testMinMaxDate() {
        verifyMinMaxDate(mDatePickerSpinnerMode);
        verifyMinMaxDate(mDatePickerCalendarMode);
    }

    private void verifyFirstDayOfWeek(DatePicker datePicker) {
        datePicker.setFirstDayOfWeek(Calendar.TUESDAY);
        assertEquals(Calendar.TUESDAY, datePicker.getFirstDayOfWeek());

        datePicker.setFirstDayOfWeek(Calendar.SUNDAY);
        assertEquals(Calendar.SUNDAY, datePicker.getFirstDayOfWeek());
    }

    @UiThreadTest
    @Test
    public void testFirstDayOfWeek() {
        verifyFirstDayOfWeek(mDatePickerSpinnerMode);
        verifyFirstDayOfWeek(mDatePickerCalendarMode);
    }

    @UiThreadTest
    @Test
    public void testCalendarViewInSpinnerMode() {
        assertNotNull(mDatePickerSpinnerMode.getCalendarView());

        // Update the DatePicker and test that its CalendarView is synced to the same date
        final Calendar calendar = new GregorianCalendar();
        calendar.set(Calendar.YEAR, 2008);
        calendar.set(Calendar.MONTH, Calendar.SEPTEMBER);
        calendar.set(Calendar.DAY_OF_MONTH, 23);
        mDatePickerSpinnerMode.updateDate(
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH));

        final Calendar calendarFromSpinner = new GregorianCalendar();
        final long timeFromSpinnerCalendar = mDatePickerSpinnerMode.getCalendarView().getDate();
        calendarFromSpinner.setTimeInMillis(timeFromSpinnerCalendar);

        assertEquals(calendar.get(Calendar.YEAR), calendarFromSpinner.get(Calendar.YEAR));
        assertEquals(calendar.get(Calendar.MONTH), calendarFromSpinner.get(Calendar.MONTH));
        assertEquals(calendar.get(Calendar.DAY_OF_MONTH),
                calendarFromSpinner.get(Calendar.DAY_OF_MONTH));
    }

    @UiThreadTest
    @Test
    public void testPartsVisibilityInSpinnerMode() {
        assertTrue(mDatePickerSpinnerMode.getSpinnersShown());
        assertTrue(mDatePickerSpinnerMode.getCalendarViewShown());

        mDatePickerSpinnerMode.setSpinnersShown(false);
        assertFalse(mDatePickerSpinnerMode.getSpinnersShown());
        assertTrue(mDatePickerSpinnerMode.getCalendarViewShown());

        mDatePickerSpinnerMode.setCalendarViewShown(false);
        assertFalse(mDatePickerSpinnerMode.getSpinnersShown());
        assertFalse(mDatePickerSpinnerMode.getCalendarViewShown());

        mDatePickerSpinnerMode.setSpinnersShown(true);
        assertTrue(mDatePickerSpinnerMode.getSpinnersShown());
        assertFalse(mDatePickerSpinnerMode.getCalendarViewShown());

        mDatePickerSpinnerMode.setCalendarViewShown(true);
        assertTrue(mDatePickerSpinnerMode.getSpinnersShown());
        assertTrue(mDatePickerSpinnerMode.getCalendarViewShown());
    }

    @UiThreadTest
    @Test
    public void testAccessInstanceState() {
        MockDatePicker datePicker = new MockDatePicker(mActivity);

        datePicker.updateDate(2008, 9, 10);
        SparseArray<Parcelable> container = new SparseArray<Parcelable>();

        // Test saveHierarchyState -> onSaveInstanceState path
        assertEquals(View.NO_ID, datePicker.getId());
        datePicker.setId(99);
        assertFalse(datePicker.hasCalledOnSaveInstanceState());
        datePicker.saveHierarchyState(container);
        assertEquals(1, datePicker.getChildCount());
        assertTrue(datePicker.hasCalledOnSaveInstanceState());

        // Test dispatchRestoreInstanceState -> onRestoreInstanceState path
        datePicker = new MockDatePicker(mActivity);
        datePicker.setId(99);
        assertFalse(datePicker.hasCalledOnRestoreInstanceState());
        datePicker.dispatchRestoreInstanceState(container);
        assertValues(datePicker, 2008, 9, 10);
        assertTrue(datePicker.hasCalledOnRestoreInstanceState());
    }

    @UiThreadTest
    @Test
    public void testAutofill() {
        verifyAutofill(mDatePickerSpinnerMode);
        verifyAutofill(mDatePickerCalendarMode);
    }

    private void verifyAutofill(DatePicker datePicker) {
        datePicker.setEnabled(true);

        final AtomicInteger numberOfListenerCalls = new AtomicInteger();
        datePicker.setOnDateChangedListener(
                (v, y, m, d) -> numberOfListenerCalls.incrementAndGet());

        final Calendar calendar = new GregorianCalendar();
        calendar.set(2012, Calendar.DECEMBER, 21);

        final AutofillValue autofilledValue = AutofillValue.forDate(calendar.getTimeInMillis());
        datePicker.autofill(autofilledValue);
        assertEquals(autofilledValue, datePicker.getAutofillValue());
        assertValues(datePicker, 2012, Calendar.DECEMBER, 21);
        assertEquals(1, numberOfListenerCalls.get());

        // Make sure autofill() is ignored when value is null.
        numberOfListenerCalls.set(0);
        datePicker.autofill((AutofillValue) null);
        assertEquals(autofilledValue, datePicker.getAutofillValue());
        assertValues(datePicker, 2012, Calendar.DECEMBER, 21);
        assertEquals(datePicker.getAutofillValue(), autofilledValue);
        assertEquals(0, numberOfListenerCalls.get());

        // Make sure autofill() is ignored when value is not a date.
        numberOfListenerCalls.set(0);
        datePicker.autofill(AutofillValue.forText("Y U NO IGNORE ME?"));
        assertEquals(autofilledValue, datePicker.getAutofillValue());
        assertValues(datePicker, 2012, Calendar.DECEMBER, 21);
        assertEquals(datePicker.getAutofillValue(), autofilledValue);
        assertEquals(0, numberOfListenerCalls.get());

        // Make sure getAutofillValue() is reset when value is manually filled.
        datePicker.autofill(autofilledValue); // 2012-12-21
        datePicker.updateDate(2000, Calendar.JANUARY, 1);
        calendar.setTimeInMillis(datePicker.getAutofillValue().getDateValue());
        assertEquals(2000, calendar.get(Calendar.YEAR));
        assertEquals(Calendar.JANUARY, calendar.get(Calendar.MONTH));
        assertEquals(1, calendar.get(Calendar.DAY_OF_MONTH));
    }

    private void assertValues(DatePicker datePicker, int year, int month, int dayOfMonth) {
        assertEquals(year, datePicker.getYear());
        assertEquals(month, datePicker.getMonth());
        assertEquals(dayOfMonth, datePicker.getDayOfMonth());
    }

    private class MockDatePicker extends DatePicker {
        private boolean mCalledOnSaveInstanceState = false;
        private boolean mCalledOnRestoreInstanceState = false;

        public MockDatePicker(Context context) {
            super(context);
        }

        @Override
        protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
            super.dispatchRestoreInstanceState(container);
        }

        @Override
        protected Parcelable onSaveInstanceState() {
            mCalledOnSaveInstanceState = true;
            return super.onSaveInstanceState();
        }

        public boolean hasCalledOnSaveInstanceState() {
            return mCalledOnSaveInstanceState;
        }

        @Override
        protected void onRestoreInstanceState(Parcelable state) {
            mCalledOnRestoreInstanceState = true;
            super.onRestoreInstanceState(state);
        }

        public boolean hasCalledOnRestoreInstanceState() {
            return mCalledOnRestoreInstanceState;
        }
    }
}
