package fr.geobert.efficio

import android.support.test.espresso.Espresso
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.action.ViewActions.click
import android.support.test.espresso.action.ViewActions.replaceText
import android.support.test.espresso.assertion.ViewAssertions.matches
import android.support.test.espresso.matcher.ViewMatchers.*
import android.support.test.filters.LargeTest
import android.support.test.rule.ActivityTestRule
import android.support.test.runner.AndroidJUnit4
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

/**
 * [Testing Fundamentals](http://d.android.com/tools/testing/testing_android.html)
 */
@RunWith(AndroidJUnit4::class)
@LargeTest
class EfficioTest {
    @Rule @JvmField var activityRule: ActivityTestRule<MainActivity> =
            ActivityTestRule(MainActivity::class.java)

    init {
        MainActivity.TEST_MODE = true
    }

    @Test fun testEnterSameItem() {
        addItem(ITEM_A, DEP_A)
        checkTaskListSize(1)

        addItem(ITEM_A)
        checkTaskListSize(1)
    }

    @Test fun testEditItemName() {
        addItem(ITEM_A, DEP_A)
        clickOnTask(0)

        onView(withId(R.id.item_name_edt)).perform(replaceText(ITEM_B))
        onView(withId(R.id.confirm)).perform(click())
        onView(withText(ITEM_B)).check(matches(isDisplayed()))
    }

    // check the sort after drag an item
    @Test fun testSort2Items() {
        addItem(ITEM_A, DEP_B)
        checkTaskListSize(1)

        addItem(ITEM_B, DEP_A)
        checkTaskListSize(2)

        // check dep order in dep editor
        clickInDrawer(R.id.edit_departments)
        checkOrderOfDeps(DEP_B, DEP_A)
        Espresso.pressBack()
        pauseTest(300)

        // creating an item, weight = max weight + 1, so B is last
        checkOrderOfTask(ITEM_A, ITEM_B)

        // drag B above A
        dragTask(1, Direction.UP)
        checkOrderOfTask(ITEM_B, ITEM_A)

        // set B as done
        clickTickOfTaskAt(0)

        // B going to bottom, A should be first
        checkOrderOfTask(ITEM_A, COMPLETED, ITEM_B)

        // uncheck B, position is 2 and not 1 because of header
        clickTickOfTaskAt(2)

        // B should go back to first pos
        checkOrderOfTask(ITEM_B, ITEM_A)

        // go to dep editor and back to refresh list and check order again
        clickInDrawer(R.id.edit_departments)
        // check order, as Item B is in Dep A, Dep A should be 1st after Item B was dragged up
        checkOrderOfDeps(DEP_A, DEP_B)
        Espresso.pressBack()
        pauseTest(300)
        checkOrderOfTask(ITEM_B, ITEM_A)

        // change dep order
        clickInDrawer(R.id.edit_departments)
        dragDep(1, Direction.UP)
        checkOrderOfDeps(DEP_B, DEP_A)
        Espresso.pressBack()
        checkOrderOfTask(ITEM_A, ITEM_B)

    }

    @Test fun testSort3Items() {
        addItem(ITEM_A, DEP_B)
        addItem(ITEM_B, DEP_B)
        addItem(ITEM_C, DEP_B)
        checkOrderOfTask(ITEM_A, ITEM_B, ITEM_C)

        // drag C above B
        dragTask(2, Direction.UP)
        checkOrderOfTask(ITEM_A, ITEM_C, ITEM_B)
        clickInDrawer(R.id.edit_departments)
        Espresso.pressBack()
        pauseTest(300)
        checkOrderOfTask(ITEM_A, ITEM_C, ITEM_B)

        addItem(ITEM_D, DEP_A)
        checkOrderOfTask(ITEM_A, ITEM_C, ITEM_B, ITEM_D)

        // drag D above B
        dragTask(3, Direction.UP)
        // D has diff dep as others, so its dep going above their dep, hence D is first
        checkOrderOfTask(ITEM_D, ITEM_A, ITEM_C, ITEM_B)
        clickInDrawer(R.id.edit_departments)
        Espresso.pressBack()
        pauseTest(300)
        checkOrderOfTask(ITEM_D, ITEM_A, ITEM_C, ITEM_B)

        // tick D, should fall at the bottom
        clickTickOfTaskAt(0)
        checkOrderOfTask(ITEM_A, ITEM_C, ITEM_B, COMPLETED, ITEM_D)

        // tick A
        clickTickOfTaskAt(0)
        checkOrderOfTask(ITEM_C, ITEM_B, COMPLETED, ITEM_D, ITEM_A)

        // untick D
        clickTickOfTaskAt(3)
        checkOrderOfTask(ITEM_D, ITEM_C, ITEM_B, COMPLETED, ITEM_A)

        // untick A
        clickTickOfTaskAt(4)
        checkOrderOfTask(ITEM_D, ITEM_A, ITEM_C, ITEM_B)

        // drag D under A
        dragTask(0, Direction.DOWN)
        checkOrderOfTask(ITEM_A, ITEM_C, ITEM_B, ITEM_D)

        // drag C above A
        dragTask(1, Direction.UP)
        checkOrderOfTask(ITEM_C, ITEM_A, ITEM_B, ITEM_D)

        // tick A
        clickTickOfTaskAt(1)
        checkOrderOfTask(ITEM_C, ITEM_B, ITEM_D, COMPLETED, ITEM_A)

        // untick A
        clickTickOfTaskAt(4)
        checkOrderOfTask(ITEM_C, ITEM_A, ITEM_B, ITEM_D)
    }


    @Test fun testChangeItemDep() {
        addItem(ITEM_A, DEP_B)
        addItem(ITEM_B, DEP_A)
        addItem(ITEM_C, DEP_A)
        checkOrderOfTask(ITEM_A, ITEM_B, ITEM_C)

        // put C above A, so it get some weight
        dragTask(2, Direction.UP, 2)
        checkOrderOfTask(ITEM_C, ITEM_B, ITEM_A)

        // change C dep to the same as A, should reset item's weight, so under B
        clickOnTask(0)
        Espresso.closeSoftKeyboard()
        onView(withText(DEP_B)).perform(click())
        onView(withId(R.id.confirm)).perform(click())
        checkOrderOfTask(ITEM_B, ITEM_A, ITEM_C)

        // add 3rd dep
        addItem(ITEM_D, DEP_C)
        checkOrderOfTask(ITEM_B, ITEM_A, ITEM_C, ITEM_D)

        // drag D between A and C, should end between B and A
        dragTask(3, Direction.UP)
        checkOrderOfTask(ITEM_B, ITEM_D, ITEM_A, ITEM_C)

        dragTask(2, Direction.UP)
        checkOrderOfTask(ITEM_B, ITEM_A, ITEM_C, ITEM_D)

        dragTask(1, Direction.DOWN)
        checkOrderOfTask(ITEM_B, ITEM_C, ITEM_A, ITEM_D)

        dragTask(3, Direction.UP)
        checkOrderOfTask(ITEM_B, ITEM_D, ITEM_C, ITEM_A)

        addItem(ITEM_E, DEP_D)
        checkOrderOfTask(ITEM_B, ITEM_D, ITEM_C, ITEM_A, ITEM_E)

        dragTask(4, Direction.UP)
        checkOrderOfTask(ITEM_B, ITEM_D, ITEM_E, ITEM_C, ITEM_A)
    }

}