package com.kdanmobile.kdan_others_library_for_android.dash2fullscreen;

import android.content.Context;
import android.content.SharedPreferences;
import androidx.test.InstrumentationRegistry;
import androidx.test.runner.AndroidJUnit4;

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

import java.lang.reflect.Method;

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

/**
 * Created by Wei on 2017/6/2.
 */
@RunWith(AndroidJUnit4.class)
public class Dash2FullScreenAdControllerTest {
    private Dash2FullScreenAdController controller;

    @Before
    public void setUp() throws Exception {
        Context context = InstrumentationRegistry.getContext();
        controller = new Dash2FullScreenAdController(context);
        clearSP(controller);
    }

    @After
    public void tearDown() throws Exception {
        clearSP(controller);
    }

    private void clearSP(Dash2FullScreenAdController controller) throws Exception {
        Method m = Dash2FullScreenAdController.class.getDeclaredMethod("getSP");
        m.setAccessible(true);
        SharedPreferences sp = (SharedPreferences) m.invoke(controller);
        sp.edit().clear().commit();
    }

    private boolean checkToShowInTargetScreen(long current) throws Exception {
        Method m = controller.getClass().getDeclaredMethod("tryToShowInTargetScreen", Runnable.class, long.class);
        m.setAccessible(true);
        return (boolean) m.invoke(controller, null, current);
    }

    @Test
    public void showInUpgradeCorrectly() throws Exception {
        assertTrue(controller.tryToShowInUpgrade(null));
        assertFalse(controller.tryToShowInUpgrade(null));
    }

    @Test
    public void showInTargetCorrectlyWithDefaultConfig() throws Exception {
        long current = System.currentTimeMillis();
        assertFalse(checkToShowInTargetScreen(current));
        assertFalse(checkToShowInTargetScreen(current));

        current += 1000;
        assertFalse(checkToShowInTargetScreen(current));

        current += 2 * 24 * 60 * 60 * 1000;
        assertTrue(checkToShowInTargetScreen(current));
        current += 1 * 24 * 60 * 60 * 1000;
        assertFalse(checkToShowInTargetScreen(current));

        current += 2 * 24 * 60 * 60 * 1000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount();
        assertFalse(checkToShowInTargetScreen(current));

        current += 2 * 24 * 60 * 60 * 1000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount();
        assertFalse(checkToShowInTargetScreen(current));

        current += 2 * 24 * 60 * 60 * 1000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount();
        assertFalse(checkToShowInTargetScreen(current));

        current += 2 * 24 * 60 * 60 * 1000;
        assertFalse(checkToShowInTargetScreen(current));
        current += 2 * 24 * 60 * 60 * 1000;
        assertFalse(checkToShowInTargetScreen(current));
    }

    @Test
    public void showInTargetCorrectlyWithSpecificConfig() throws Exception {
        Dash2FullScreenAdController.Config config = new Dash2FullScreenAdController.Config();
        config.maxTimesLeaveDirectlyInTargetScreen = 5;
        config.firstShowInTargetScreenInterval = 1000;
        config.routineShowInTargetScreenInterval= 5000;
        controller.setConfig(config);
        long current = System.currentTimeMillis();
        assertFalse(checkToShowInTargetScreen(current));
        assertFalse(checkToShowInTargetScreen(current));

        current += 100;
        assertFalse(checkToShowInTargetScreen(current));

        current += 1000;
        assertTrue(checkToShowInTargetScreen(current));
        current += 1000;
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount(); // 1
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount(); // 2
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount(); // 3
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount(); // 4
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertTrue(checkToShowInTargetScreen(current));
        controller.increaseLeaveDirectlyCount(); // 5
        assertFalse(checkToShowInTargetScreen(current));

        current += 5000;
        assertFalse(checkToShowInTargetScreen(current));
        current += 5000;
        assertFalse(checkToShowInTargetScreen(current));
    }
}