import org.serviio.library.metadata.MediaFileType
import org.serviio.library.online.WebResourceUrlExtractor
import org.serviio.library.online.WebResourceContainer
import org.serviio.library.online.ContentURLContainer
import org.serviio.library.online.WebResourceItem
import org.serviio.library.online.PreferredQuality
import groovy.json.JsonSlurper


class WeebTV extends WebResourceUrlExtractor {


    /* -------------- CREDENTIALS -------------------------------- */
    final static USERNAME = '' // weeb.tv username
    final static PASSWORD = '' // weeb.tv password
    /* ----------------------------------------------------------- */


    /* -------------- SETTINGS ----------------------------------- */
    final static VALID_WEB_RESOURCE_URL = '^http://weeb.tv$'
    final static MAIN_URL = 'http://weeb.tv'
    final static CHANNELS_URL = MAIN_URL + '/api/getChannelList&option=online-alphabetical'
    final static PLAYER_URL = MAIN_URL + '/api/setPlayer'
    final static USER_AGENT = 'XBMC'
    final static PLATFORM = USER_AGENT
    final static ONLINE_INDICATOR = '2'
    /* ----------------------------------------------------------- */


    @Override
    protected WebResourceContainer extractItems(URL url, int i) {

        List<WebResourceItem> items = []
        getAvailableChannels().each {
            key, value ->
                Map<String, String> additionalInfo = new LinkedHashMap<>()
                additionalInfo.put("channelID",(String)key)
                    items.add(new WebResourceItem(title: value, additionalInfo: additionalInfo))
                //println "Title: ${value} ChannelID: ${key}"
        }
        return new WebResourceContainer(title: "Weeb TV", items: items)
    }

    private static Map getAvailableChannels() {
        def headers = ["ContentType": "application/x-www-form-urlencoded"]
        def postData = 'username=' + USERNAME + '&userpassword=' + PASSWORD
        def channels = postRequest(new URL(CHANNELS_URL), postData, headers)
        def jsonSlurper = new JsonSlurper()
        def object = jsonSlurper.parseText(channels)
        def availableChannels = [:]
        object.each { key, value ->
            if (value.channel_online == ONLINE_INDICATOR) availableChannels.put(value.cid, value.channel_title) }
        return availableChannels;
    }

    @Override
    protected ContentURLContainer extractUrl(WebResourceItem webResourceItem, PreferredQuality preferredQuality) {
        def channelID = webResourceItem.getAdditionalInfo().get("channelID")
        def media = getChannelProperties(channelID)

        ContentURLContainer contentURLContainer = new ContentURLContainer();
        contentURLContainer.contentUrl = media.rtmpLink;
        contentURLContainer.thumbnailUrl = media.imgLink;
        contentURLContainer.live = true
        contentURLContainer.expiresImmediately = true
        contentURLContainer.fileType = MediaFileType.VIDEO
        contentURLContainer.cacheKey = media.cacheKey
        contentURLContainer.userAgent = USER_AGENT

        return contentURLContainer
    }

    @Override
    boolean extractorMatches(URL url) {
        return url ==~ VALID_WEB_RESOURCE_URL
    }

    @Override
    String getExtractorName() {
        return "WeebTV"
    }


    private WeebTVMedia getChannelProperties(String channelID) {
        def response = sendRequestForMedia(channelID)
        def paramMap = response.split('&').collectEntries { param ->
            param.split('=').collect { URLDecoder.decode(it, "UTF-8") }
        }
        def status = paramMap['0']
        def premium = paramMap['5']
        def imgLink = paramMap['8']
        def rtmpLink = paramMap['10']
        def playPath = paramMap['11']
        def bitrate = paramMap['20']
        def token = paramMap['73']
        def title = paramMap['6']
        if (title == '')
            title = paramMap['7']
        if (bitrate == '1')
            playPath += 'HI'
        else if (bitrate == '2')
            playPath += 'LOW'

        def rtmp = rtmpLink + '/' + playPath + ' live=true pageUrl=token swfUrl=' + token

        return new WeebTVMedia(rtmp, imgLink, token + bitrate);
    }

    private static String sendRequestForMedia(String channelID) {
        def postData = "platform=" + PLATFORM + "&channel=" + channelID + "&username=" + USERNAME + "&userpassword=" + PASSWORD
        return postRequest(new URL(PLAYER_URL), postData, Collections.emptyMap())
    }


    private static String postRequest(URL url, String postData, Map<String, String> headers) {
        def connection = url.openConnection()
        connection.setRequestMethod("POST")
        connection.setRequestProperty("User-Agent", USER_AGENT)
        headers.each { key, value -> connection.setRequestProperty(key, value) }
        connection.setUseCaches(false);
        connection.setAllowUserInteraction(false);
        connection.doOutput = true
        def writer = new OutputStreamWriter(connection.outputStream)
        writer.write(postData)
        writer.flush()
        writer.close()
        connection.connect()
        return connection.content.text
    }

    class WeebTVMedia {
        def rtmpLink;
        def imgLink;
        def cacheKey;

        WeebTVMedia(rtmpLink, imgLink, cacheKey) {
            this.rtmpLink = rtmpLink
            this.imgLink = imgLink
            this.cacheKey = cacheKey
        }
    }

    /**
     * Only for test and debug
     * @param args
     */
    static void main(args) {
        def TestUrl = new URL("http://weeb.tv")
        WeebTV extractor = new WeebTV()
        println "PluginName : " + extractor.getExtractorName();
        println "TestMatch  : " + extractor.extractorMatches(TestUrl);
        WebResourceContainer container = extractor.extractItems(TestUrl, -1);
        container.getItems().each {
            ContentURLContainer urlContainer = extractor.extractUrl(it, PreferredQuality.HIGH)
            println it.title +" (" + it.additionalInfo.channelID+") "+urlContainer.contentUrl
        }
    }


}
