package com.rssuper.parsing

import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config

@RunWith(RobolectricTestRunner::class)
@Config(sdk = [24])
class FeedParserTest {

    @Test
    fun testParseRSSFeed() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <rss version="2.0">
                <channel>
                    <title>RSS Feed</title>
                    <link>https://example.com</link>
                    <item>
                        <title>Item</title>
                        <link>https://example.com/item</link>
                    </item>
                </channel>
            </rss>
        """.trimIndent()

        val result = FeedParser.parse(xml, "https://example.com/feed.xml")

        assertNotNull(result)
        assertEquals(FeedType.RSS, result.feedType)
        assertEquals("RSS Feed", result.feed.title)
    }

    @Test
    fun testParseAtomFeed() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom">
                <title>Atom Feed</title>
                <id>urn:uuid:feed</id>
                <entry>
                    <title>Entry</title>
                    <id>urn:uuid:entry</id>
                </entry>
            </feed>
        """.trimIndent()

        val result = FeedParser.parse(xml, "https://example.com/feed.atom")

        assertNotNull(result)
        assertEquals(FeedType.Atom, result.feedType)
        assertEquals("Atom Feed", result.feed.title)
    }

    @Test
    fun testParseRSSWithNamespaces() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
                <channel>
                    <title>Namespaced Feed</title>
                    <atom:link href="https://example.com/feed.xml" rel="self"/>
                    <itunes:author>Author</itunes:author>
                    <item>
                        <title>Item</title>
                    </item>
                </channel>
            </rss>
        """.trimIndent()

        val result = FeedParser.parse(xml, "https://example.com/feed.xml")

        assertNotNull(result)
        assertEquals(FeedType.RSS, result.feedType)
    }

    @Test
    fun testParseMalformedXml() {
        val malformedXml = """
            <?xml version="1.0"?>
            <rss>
                <channel>
                    <title>Broken
            """.trimIndent()

        try {
            val result = FeedParser.parse(malformedXml, "https://example.com/feed.xml")
            assertNotNull(result)
        } catch (e: Exception) {
            assertNotNull(e)
        }
    }

    @Test
    fun testParseInvalidFeedType() {
        val invalidXml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <invalid>
                <data>Some data</data>
            </invalid>
        """.trimIndent()

        try {
            FeedParser.parse(invalidXml, "https://example.com/feed.xml")
            fail("Expected exception for invalid feed type")
        } catch (e: FeedParsingError) {
            assertEquals(FeedParsingError.UnsupportedFeedType, e)
        }
    }

    @Test
    fun testParseEmptyFeed() {
        val emptyXml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <rss version="2.0">
                <channel>
                    <title></title>
                </channel>
            </rss>
        """.trimIndent()

        val result = FeedParser.parse(emptyXml, "https://example.com/feed.xml")

        assertNotNull(result)
        assertEquals("Untitled Feed", result.feed.title)
    }

    @Test
    fun testAsyncCallback() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <rss version="2.0">
                <channel>
                    <title>Async Feed</title>
                    <item>
                        <title>Item</title>
                    </item>
                </channel>
            </rss>
        """.trimIndent()

        FeedParser.parseAsync(xml, "https://example.com/feed.xml") { result ->
            assert(result.isSuccess)
            val feed = result.getOrNull()
            assertNotNull(feed)
            assertEquals("Async Feed", feed?.feed?.title)
        }
    }

    @Test
    fun testAsyncCallbackError() {
        val invalidXml = "not xml"

        FeedParser.parseAsync(invalidXml, "https://example.com/feed.xml") { result ->
            assert(result.isFailure)
        }
    }
}
