package com.kdanmobile.kdan_others_library_for_android

import com.kdanmobile.kdan_others_library_for_android.utils.SpannableStringHelper
import org.junit.Test

import org.junit.Assert.*

class SpannableStringHelperTest {

    /**
     * 單個標籤測試
     * This is a <t1>red</t1> apple.
     */
    @Test
    @Throws(Exception::class)
    fun singleTagTest() {
        val spannableInfo = SpannableStringHelper().extractSpannableInfo(
                "This is a " +
                        "[CTRL-START b,i,u:tag1]red[CTRL-END]" +
                        " apple.",
                listOf("tag1")
        )
        assertEquals("This is a red apple.", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("red", text)
                assertEquals(10, startIndex)
                assertEquals(13, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(true, isBold)
                assertEquals(true, isItalic)
                assertEquals(false, isStrikeThrough)
            }
        }
    }

    /**
     * 多個相同標籤
     * This <t1>is a</t1> red <t1>apple</t1>.
     */
    @Test
    @Throws(Exception::class)
    fun multipleSameTagTest() {
        val spannableInfo = SpannableStringHelper().extractSpannableInfo(
                "This " +
                        "[CTRL-START b,i,u:tag1]is a[CTRL-END]" +
                        " red " +
                        "[CTRL-START s,u:tag1]apple[CTRL-END].",
                listOf("tag1")
        )
        assertEquals("This is a red apple.", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(2, it.size)
            it[0].run {
                assertEquals("is a", text)
                assertEquals(5, startIndex)
                assertEquals(9, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(true, isBold)
                assertEquals(true, isItalic)
                assertEquals(false, isStrikeThrough)
            }
            it[1].run {
                assertEquals("apple", text)
                assertEquals(14, startIndex)
                assertEquals(19, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(false, isBold)
                assertEquals(false, isItalic)
                assertEquals(true, isStrikeThrough)
            }
        }
    }

    /**
     * 多個不同標籤，忽略處理其他標籤
     * This <t1>is a</t1> red <t2>apple</t2>.
     * */
    @Test
    @Throws(Exception::class)
    fun multipleTagsAndIgnoreOthersTest() {
        val spannableInfo = SpannableStringHelper().extractSpannableInfo(
                "This " +
                        "[CTRL-START b,i,u:tag1]is a[CTRL-END]" +
                        " red " +
                        "[CTRL-START s,u:tag2]apple[CTRL-END].",
                listOf("tag1"),
                true
        )
        assertEquals("This is a red [CTRL-START s,u:tag2]apple[CTRL-END].", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        assertNull(spannableInfo.tagMap["tag2"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("is a", text)
                assertEquals(5, startIndex)
                assertEquals(9, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(true, isBold)
                assertEquals(true, isItalic)
                assertEquals(false, isStrikeThrough)
            }
        }
    }

    /**
     * 多個不同標籤，不忽略處理其他標籤（tags將被忽略）
     * This <t1>is a</t1> red <t2>apple</t2>.
     * */
    @Test
    @Throws(Exception::class)
    fun multipleTagsTest() {
        val spannableStringHelper = SpannableStringHelper()
        val spannableInfo = spannableStringHelper.extractSpannableInfo(
                "This " +
                        "[CTRL-START b,i,u:tag1]is a[CTRL-END]" +
                        " red " +
                        "[CTRL-START s,u:tag2]apple[CTRL-END].",
                listOf("tag1"),
                false
        )
        assertEquals("This is a red apple.", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        assertNotNull(spannableInfo.tagMap["tag2"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("is a", text)
                assertEquals(5, startIndex)
                assertEquals(9, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(true, isBold)
                assertEquals(true, isItalic)
                assertEquals(false, isStrikeThrough)
            }
        }
        spannableInfo.tagMap["tag2"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("apple", text)
                assertEquals(14, startIndex)
                assertEquals(19, endIndex)
                assertEquals(true, isUnderline)
                assertEquals(false, isBold)
                assertEquals(false, isItalic)
                assertEquals(true, isStrikeThrough)
            }
        }
    }

    /**
     * 處理所有標籤
     * <t1>This </t1><t2>is a</t2> <t3>red<t3> <t2>apple</t2>.
     */
    @Test
    @Throws(Exception::class)
    fun allTagsTest() {
        val spannableStringHelper = SpannableStringHelper()
        val spannableInfo = spannableStringHelper.extractSpannableInfo(
                "[CTRL-START :tag1]This [CTRL-END]" +
                        "[CTRL-START :tag2]is a[CTRL-END] " +
                        "[CTRL-START :tag3]red[CTRL-END] " +
                        "[CTRL-START :tag2]apple[CTRL-END]."
        )
        assertEquals("This is a red apple.", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        assertNotNull(spannableInfo.tagMap["tag2"])
        assertNotNull(spannableInfo.tagMap["tag3"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("This ", text)
                assertEquals(0, startIndex)
                assertEquals(5, endIndex)
            }
        }
        spannableInfo.tagMap["tag2"]?.also {
            assertEquals(2, it.size)
            it[0].run {
                assertEquals("is a", text)
                assertEquals(5, startIndex)
                assertEquals(9, endIndex)
            }
            it[1].run {
                assertEquals("apple", text)
                assertEquals(14, startIndex)
                assertEquals(19, endIndex)
            }
        }
        spannableInfo.tagMap["tag3"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("red", text)
                assertEquals(10, startIndex)
                assertEquals(13, endIndex)
            }
        }
    }

    /**
     * 處理快捷設置
     * <Q:t1>This is a</Q:t1> <t2>red<t2> apple.
     */
    @Test
    @Throws(Exception::class)
    fun quickSettingTest() {
        val spannableStringHelper = SpannableStringHelper()
        val spannableInfo = spannableStringHelper.extractSpannableInfo(
                "[CTRL-START <Term of Use>:tag1]This is a[CTRL-END] " +
                        "[CTRL-START :tag2]red[CTRL-END] " +
                        "apple."
        )
        assertEquals("This is a red apple.", spannableInfo.displayText)
        assertNotNull(spannableInfo.tagMap["tag1"])
        assertNotNull(spannableInfo.tagMap["tag2"])
        spannableInfo.tagMap["tag1"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("This is a", text)
                assertEquals(0, startIndex)
                assertEquals(9, endIndex)
                assertEquals(false, isUnderline)
                assertEquals(true, isBold)
                assertEquals(false, isItalic)
                assertEquals(false, isStrikeThrough)
            }
        }
        spannableInfo.tagMap["tag2"]?.also {
            assertEquals(1, it.size)
            it[0].run {
                assertEquals("red", text)
                assertEquals(10, startIndex)
                assertEquals(13, endIndex)
            }
        }
    }
}