package com.android.clockwork.common;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.shadows.ShadowLooper;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;

@RunWith(RobolectricTestRunner.class)
public class RadioTogglerTest {

    /**
     * A mock Radio implementation is favored here because it leads to clearer test code
     * that more closely mirrors real-world usage.  A Mockito version of Radio would
     * result in some weird mock method declarations in order for the RadioToggler to
     * properly interact with the mock radio.
     */
    private class MockRadio implements RadioToggler.Radio {

        private volatile boolean enabled = false;
        volatile int numSetEnables = 0;

        @Override
        public String logTag() {
            return "MockRadio";
        }

        @Override
        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
            numSetEnables++;
        }

        @Override
        public boolean getEnabled() {
            return enabled;
        }
    }


    private @Mock PartialWakeLock mockWakeLock;
    private MockRadio mockRadio;
    private RadioToggler radioToggler;

    private ShadowLooper shadowLooper;

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

        mockRadio = new MockRadio();
        radioToggler = new RadioToggler(mockRadio, mockWakeLock, -1);

        shadowLooper = shadowOf(radioToggler.mHandlerThread.getLooper());
        shadowLooper.pause();
    }

    @Test
    public void testGetRadioEnabled() {
        // the value here should match mockRadio's value before construction
        assertFalse(radioToggler.getRadioEnabled());

        // changing the state of the radio should not directly affect RadioToggler
        mockRadio.setEnabled(true);
        assertFalse(radioToggler.getRadioEnabled());
    }

    @Test
    public void testRefreshRadioState() {
        mockRadio.setEnabled(true);
        radioToggler.refreshRadioState();
        shadowLooper.runToEndOfTasks();
        assertTrue(radioToggler.getRadioEnabled());

        mockRadio.setEnabled(false);
        radioToggler.refreshRadioState();
        shadowLooper.runToEndOfTasks();
        assertFalse(radioToggler.getRadioEnabled());
    }

    /**
     * Used by subsequent tests, this helper method assumes testRefreshRadioState passes.
     */
    private void setRadioInitialState(boolean enabled) {
        mockRadio.setEnabled(enabled);
        mockRadio.numSetEnables = 0;
        radioToggler.refreshRadioState();
        shadowLooper.runToEndOfTasks();
    }

    @Test
    public void testToggleRadioOn() {
        setRadioInitialState(false);

        radioToggler.toggleRadio(true);
        shadowLooper.runToEndOfTasks();

        verify(mockWakeLock).acquire();
        verify(mockWakeLock).release();

        assertTrue(radioToggler.getRadioEnabled());
        assertTrue(mockRadio.getEnabled());
        assertEquals(1, mockRadio.numSetEnables);
    }

    @Test
    public void testToggleRadioOff() {
        setRadioInitialState(true);

        radioToggler.toggleRadio(false);
        shadowLooper.runToEndOfTasks();

        verify(mockWakeLock).acquire();
        verify(mockWakeLock).release();
        assertFalse(radioToggler.getRadioEnabled());
        assertFalse(mockRadio.getEnabled());
        assertEquals(1, mockRadio.numSetEnables);
    }

    @Test
    public void testToggleRadioOnWhenAlreadyOn() {
        setRadioInitialState(true);

        radioToggler.toggleRadio(true);
        shadowLooper.runToEndOfTasks();

        verifyNoMoreInteractions(mockWakeLock);

        assertTrue(radioToggler.getRadioEnabled());
        assertTrue(mockRadio.getEnabled());
        assertEquals(0, mockRadio.numSetEnables);
    }

    @Test
    public void testToggleRadioOffWhenAlreadyOff() {
        setRadioInitialState(false);

        radioToggler.toggleRadio(false);
        shadowLooper.runToEndOfTasks();

        verifyNoMoreInteractions(mockWakeLock);

        assertFalse(radioToggler.getRadioEnabled());
        assertFalse(mockRadio.getEnabled());
        assertEquals(0, mockRadio.numSetEnables);
    }

    @Test
    public void testMultipleTogglesLastOneWins() {
        setRadioInitialState(true);

        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(false);
        shadowLooper.runToEndOfTasks();

        verify(mockWakeLock).acquire();
        verify(mockWakeLock).release();

        assertFalse(radioToggler.getRadioEnabled());
        assertFalse(mockRadio.getEnabled());
        assertEquals(1, mockRadio.numSetEnables);
    }

    @Test
    public void testMultipleTogglesToSameState() {
        setRadioInitialState(true);

        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(true);
        radioToggler.toggleRadio(false);
        radioToggler.toggleRadio(true);
        shadowLooper.runToEndOfTasks();

        verifyNoMoreInteractions(mockWakeLock);

        assertTrue(radioToggler.getRadioEnabled());
        assertTrue(mockRadio.getEnabled());
        assertEquals(0, mockRadio.numSetEnables);
    }
}
