package com.rssuper.parsing

import com.rssuper.models.Enclosure
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
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 AtomParserTest {

    @Test
    fun testParseBasicAtom() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom">
                <title>Atom Feed</title>
                <subtitle>Feed subtitle</subtitle>
                <link href="https://example.com" rel="alternate"/>
                <id>urn:uuid:feed-id-123</id>
                <updated>2024-01-01T12:00:00Z</updated>
                <generator>Atom Generator</generator>
                <entry>
                    <title>Entry 1</title>
                    <link href="https://example.com/entry1" rel="alternate"/>
                    <id>urn:uuid:entry-1</id>
                    <updated>2024-01-01T10:00:00Z</updated>
                    <summary>Summary of entry 1</summary>
                </entry>
                <entry>
                    <title>Entry 2</title>
                    <link href="https://example.com/entry2" rel="alternate"/>
                    <id>urn:uuid:entry-2</id>
                    <updated>2023-12-31T10:00:00Z</updated>
                    <content>Full content of entry 2</content>
                </entry>
            </feed>
        """.trimIndent()

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

        assertNotNull(feed)
        assertEquals("Atom Feed", feed.title)
        assertEquals("https://example.com", feed.link)
        assertEquals("Feed subtitle", feed.subtitle)
        assertEquals(2, feed.items.size)

        val entry1 = feed.items[0]
        assertEquals("Entry 1", entry1.title)
        assertEquals("https://example.com/entry1", entry1.link)
        assertEquals("Summary of entry 1", entry1.description)
        assertNotNull(entry1.published)

        val entry2 = feed.items[1]
        assertEquals("Entry 2", entry2.title)
        assertEquals("Full content of entry 2", entry2.content)
    }

    @Test
    fun testParseAtomWithAuthor() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom">
                <title>Author Feed</title>
                <id>urn:uuid:feed-id</id>
                <entry>
                    <title>Entry with Author</title>
                    <id>urn:uuid:entry</id>
                    <author>
                        <name>John Doe</name>
                        <email>john@example.com</email>
                    </author>
                </entry>
            </feed>
        """.trimIndent()

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertEquals("John Doe", entry.author)
    }

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

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertEquals(2, entry.categories?.size)
        assertEquals("technology", entry.categories?.get(0))
        assertEquals("programming", entry.categories?.get(1))
    }

    @Test
    fun testParseAtomWithEnclosure() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom">
                <title>Enclosure Feed</title>
                <id>urn:uuid:feed-id</id>
                <entry>
                    <title>Episode</title>
                    <id>urn:uuid:entry</id>
                    <link href="https://example.com/ep.mp3" rel="enclosure" type="audio/mpeg" length="12345678"/>
                </entry>
            </feed>
        """.trimIndent()

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertNotNull(entry.enclosure)
        assertEquals("https://example.com/ep.mp3", entry.enclosure?.url)
        assertEquals("audio/mpeg", entry.enclosure?.type)
        assertEquals(12345678L, entry.enclosure?.length)
    }

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

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertEquals("Full HTML content", entry.content)
        assertEquals("Short summary", entry.description)
    }

    @Test
    fun testParseAtomWithiTunesExtension() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
                <title>Podcast</title>
                <id>urn:uuid:feed-id</id>
                <entry>
                    <title>Episode</title>
                    <id>urn:uuid:entry</id>
                    <itunes:duration>3600</itunes:duration>
                    <itunes:summary>Episode summary</itunes:summary>
                </entry>
            </feed>
        """.trimIndent()

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertEquals("Episode summary", entry.description)
    }

    @Test
    fun testParseAtomWithPublished() {
        val xml = """
            <?xml version="1.0" encoding="UTF-8"?>
            <feed xmlns="http://www.w3.org/2005/Atom">
                <title>Date Feed</title>
                <id>urn:uuid:feed-id</id>
                <updated>2024-06-15T12:00:00Z</updated>
                <entry>
                    <title>Entry</title>
                    <id>urn:uuid:entry</id>
                    <published>2024-01-01T08:00:00Z</published>
                    <updated>2024-01-02T10:00:00Z</updated>
                </entry>
            </feed>
        """.trimIndent()

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

        assertNotNull(feed)
        val entry = feed.items[0]
        assertNotNull(entry.published)
    }

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

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

        assertNotNull(feed)
        assertEquals("Empty Feed", feed.title)
        assertEquals(0, feed.items.size)
    }

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

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

        assertNotNull(feed)
        assertEquals("Untitled Feed", feed.title)
        assertEquals(1, feed.items.size)
        assertEquals("Minimal Entry", feed.items[0].title)
        assertNull(feed.items[0].link)
    }
}
