package rasel.lunar.launcher.home.adapters

import android.util.Xml
import com.google.gson.Gson
import org.xmlpull.v1.XmlPullParser
import org.xmlpull.v1.XmlPullParserException
import rasel.lunar.launcher.model.RssDataInterface
import rasel.lunar.launcher.model.NewsData
import rasel.lunar.launcher.model.others.Reddit
import rasel.lunar.launcher.utils.beforeDay
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.net.URL
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale


object RssFeedsParser {
    var parseDateFormat: SimpleDateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH)
    var limitDateTime = beforeDay(Date(),3)
    fun getFeeds(url : String) : List<RssDataInterface> {
        var returnList =  mutableListOf<RssDataInterface>()
        try {
            returnList.addAll(parse(getInputStream(url)!!))
        } catch (e : Exception) {
            e.printStackTrace()
        }
        return returnList
    }

    fun getReddit(url : String): List<RssDataInterface> {
        var returnList =  mutableListOf<RssDataInterface>()
        var dateTime = beforeDay(Date(),3)
        try {
            var mReddit = Gson().fromJson(InputStreamReader(getInputStream(url)!!), Reddit::class.java)
            mReddit.data?.children?.forEach {
                if(((it.data?.created_utc ?: 0).toLong() * 1000L >  dateTime)) {
                    (it.data as? RssDataInterface)?.let { rss ->
                        returnList.add(rss)
                    }
                }
            }
        } catch (e : Exception) {
            e.printStackTrace()
        }
        return returnList
    }

    private fun getInputStream(link: String?): InputStream? {
        return try {
            val url = URL(link)
            url.openConnection().getInputStream()

        } catch (ioException: IOException) {
            ioException.printStackTrace()
            null
        }.apply {
        }
    }


    @Throws(XmlPullParserException::class, IOException::class)
    private fun parse(inputStream: InputStream): List<RssDataInterface> {
        return inputStream.use { stream ->
            val parser = Xml.newPullParser()
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false)
            parser.setInput(stream, null)
            parser.nextTag()
            readFeed(parser)
        }
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readFeed(parser: XmlPullParser): List<NewsData> {

        parser.require(XmlPullParser.START_TAG, null, "rss")
        var title: String? = null
        var link: String? = null
        var date = 0L
        var desc : String? = null
        var source  : String? = null
        val items: MutableList<NewsData> = ArrayList()

        while (parser.next() != XmlPullParser.END_DOCUMENT) {
            if (parser.eventType != XmlPullParser.START_TAG) {
                continue
            }

            val name = parser.name
            if (name == "title") {
                title = readTitle(parser)
            } else if (name == "link") {
                link = readLink(parser)
            } else if (name == "pubDate") {
                try {
                    date = parseDateFormat.parse(readDate(parser))?.time ?: 0L
                }catch (e : Exception) {
                    e.printStackTrace()
                }
            } else if (name == "description") {
                desc = readDesc(parser)
            } else if (name == "source") {
                source = readThumbnail(parser)
            }

            if (date > limitDateTime  && title != null && link != null) {
                val item = NewsData(title, link)
                item.pubDate = date
                item.source = source
                item.description = desc
                items.add(item)
                title = null
                link = null
                source = null
                desc = null
                date = 0
            }
        }
        return items
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readLink(parser: XmlPullParser): String {
        parser.require(XmlPullParser.START_TAG, null, "link")
        val link = readText(parser)
        parser.require(XmlPullParser.END_TAG, null, "link")
        return link
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readTitle(parser: XmlPullParser): String {
        parser.require(XmlPullParser.START_TAG, null, "title")
        val title = readText(parser)
        parser.require(XmlPullParser.END_TAG, null, "title")
        return title
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readDate(parser: XmlPullParser): String {
        parser.require(XmlPullParser.START_TAG, null, "pubDate")
        val date = readText(parser)
        parser.require(XmlPullParser.END_TAG, null, "pubDate")
        return date
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readDesc(parser: XmlPullParser): String {
        parser.require(XmlPullParser.START_TAG, null, "description")
        val link = readText(parser)
        parser.require(XmlPullParser.END_TAG, null, "description")
        return link
    }

    @Throws(XmlPullParserException::class, IOException::class)
    private fun readThumbnail(parser: XmlPullParser): String {
        parser.require(XmlPullParser.START_TAG, null, "source")
        val link = readText(parser)
        parser.require(XmlPullParser.END_TAG, null, "source")
        return link
    }


    @Throws(IOException::class, XmlPullParserException::class)
    private fun readText(parser: XmlPullParser): String {
        var result = ""
        if (parser.next() == XmlPullParser.TEXT) {
            result = parser.text
            parser.nextTag()
        }
        return result
    }
}

