/*
 * 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.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;

import android.app.Instrumentation;
import android.content.Context;
import android.os.SystemClock;
import android.view.ContextThemeWrapper;
import android.widget.Chronometer;

import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.LargeTest;
import androidx.test.filters.SmallTest;
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;

/**
 * Test {@link Chronometer}.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class ChronometerTest {
    private Instrumentation mInstrumentation;
    private ChronometerCtsActivity mActivity;

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

    @Before
    public void setup() {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivity = mActivityRule.getActivity();
    }

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

        new Chronometer(mActivity, null);

        new Chronometer(mActivity, null, 0);
    }

    @Test
    public void testConstructorFromAttr() {
        final Context context = new ContextThemeWrapper(mActivity, R.style.ChronometerAwareTheme);
        final Chronometer chronometer = new Chronometer(context, null, R.attr.chronometerStyle);
        assertTrue(chronometer.isCountDown());
        assertEquals(mActivity.getString(R.string.chronometer_format), chronometer.getFormat());
    }

    @Test
    public void testConstructorFromStyle() {
        final Chronometer chronometer = new Chronometer(mActivity, null, 0,
                R.style.ChronometerStyle);
        assertTrue(chronometer.isCountDown());
        assertEquals(mActivity.getString(R.string.chronometer_format), chronometer.getFormat());
    }

    @UiThreadTest
    @Test
    public void testAccessBase() {
        Chronometer chronometer = mActivity.getChronometer();
        CharSequence oldText = chronometer.getText();

        chronometer.setBase(100000);
        assertEquals(100000, chronometer.getBase());
        assertNotSame(oldText, chronometer.getText());

        oldText = chronometer.getText();
        chronometer.setBase(100);
        assertEquals(100, chronometer.getBase());
        assertNotSame(oldText, chronometer.getText());

        oldText = chronometer.getText();
        chronometer.setBase(-1);
        assertEquals(-1, chronometer.getBase());
        assertNotSame(oldText, chronometer.getText());

        oldText = chronometer.getText();
        chronometer.setBase(Integer.MAX_VALUE);
        assertEquals(Integer.MAX_VALUE, chronometer.getBase());
        assertNotSame(oldText, chronometer.getText());
    }

    @UiThreadTest
    @Test
    public void testAccessFormat() {
        Chronometer chronometer = mActivity.getChronometer();
        String expected = "header-%S-trail";

        chronometer.setFormat(expected);
        assertEquals(expected, chronometer.getFormat());

        chronometer.start();
        String text = chronometer.getText().toString();
        assertTrue(text.startsWith("header"));
        assertTrue(text.endsWith("trail"));
    }

    @Test
    @LargeTest
    public void testStartAndStop() throws Throwable {
        final Chronometer chronometer = mActivity.getChronometer();

        // we will check the text is really updated every 1000ms after start,
        // so we need sleep a moment to wait wait this time. The sleep code shouldn't
        // in the same thread with UI, that's why we use runOnUiThread here.
        mActivityRule.runOnUiThread(() -> {
            // the text will update immediately when call start.
            final CharSequence valueBeforeStart = chronometer.getText();
            chronometer.start();
            assertNotSame(valueBeforeStart, chronometer.getText());
        });
        mInstrumentation.waitForIdleSync();

        CharSequence expected = chronometer.getText();
        SystemClock.sleep(1500);
        assertFalse(expected.equals(chronometer.getText()));

        // we will check the text is really NOT updated anymore every 1000ms after stop,
        // so we need sleep a moment to wait wait this time. The sleep code shouldn't
        // in the same thread with UI, that's why we use runOnUiThread here.
        mActivityRule.runOnUiThread(() -> {
            // the text will never be updated when call stop.
            final CharSequence valueBeforeStop = chronometer.getText();
            chronometer.stop();
            assertSame(valueBeforeStop, chronometer.getText());
        });
        mInstrumentation.waitForIdleSync();

        expected = chronometer.getText();
        SystemClock.sleep(1500);
        assertTrue(expected.equals(chronometer.getText()));
    }

    @Test
    @LargeTest
    public void testAccessOnChronometerTickListener() throws Throwable {
        final Chronometer chronometer = mActivity.getChronometer();
        final Chronometer.OnChronometerTickListener mockTickListener =
                mock(Chronometer.OnChronometerTickListener.class);

        mActivityRule.runOnUiThread(() -> {
            chronometer.setOnChronometerTickListener(mockTickListener);
            chronometer.start();
        });
        mInstrumentation.waitForIdleSync();

        assertEquals(mockTickListener, chronometer.getOnChronometerTickListener());
        verify(mockTickListener, atLeastOnce()).onChronometerTick(chronometer);

        reset(mockTickListener);
        SystemClock.sleep(1500);
        verify(mockTickListener, atLeastOnce()).onChronometerTick(chronometer);
    }

    @Test
    @LargeTest
    public void testCountDown() throws Throwable {
        final Chronometer chronometer = mActivity.getChronometer();
        final Chronometer.OnChronometerTickListener mockTickListener =
                mock(Chronometer.OnChronometerTickListener.class);

        mActivityRule.runOnUiThread(() -> {
            chronometer.setCountDown(true);
            chronometer.setOnChronometerTickListener(mockTickListener);
            chronometer.start();
        });
        mInstrumentation.waitForIdleSync();

        assertTrue(chronometer.isCountDown());

        SystemClock.sleep(5000);
        verify(mockTickListener, atLeastOnce()).onChronometerTick(chronometer);
    }

    @Test
    @LargeTest
    public void testCountUp() throws Throwable {
        final Chronometer chronometer = mActivity.getChronometer();
        final Chronometer.OnChronometerTickListener mockTickListener =
                mock(Chronometer.OnChronometerTickListener.class);

        mActivityRule.runOnUiThread(() -> {
            chronometer.setCountDown(false);
            chronometer.setOnChronometerTickListener(mockTickListener);
            chronometer.start();
        });
        mInstrumentation.waitForIdleSync();

        assertFalse(chronometer.isCountDown());

        SystemClock.sleep(5000);
        verify(mockTickListener, atLeastOnce()).onChronometerTick(chronometer);
    }
}
