"""Plugin for Dplay channels such as Kanal 5, Kanal 9 and Kanal 11."""

import re
import time

from livestreamer.compat import quote
from livestreamer.plugin import Plugin
from livestreamer.plugin.api import StreamMapper, http, validate
from livestreamer.stream import HLSStream, HDSStream

# Interface URLs for Dplay
GENERAL_API_URL = 'http://www.dplay.se/api/v2/ajax/videos?video_id={0}'
STREAM_API_URL = 'https://secure.dplay.se/secure/api/v2/user/authorization/stream/{0}?stream_type={1}'
GEO_DATA_URL = 'http://geo.dplay.se/geo.js'

# User-agent to use for http requests
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.82 Safari/537.36'

# Regular expressions for url and parsing of video ID
_url_re = re.compile ('(http(s)?://)?www.dplay.se/')
_videoid_re = re.compile ("<link rel='shortlink' href='http://www.dplay.se/\?p=(?P<id>\d+)")

# Validation schemas
# ------------------
_api_schema = validate.Schema (
    {
        "data": validate.any (
            None,
            [{
                "video_metadata_drmid_playready": validate.text,
                "video_metadata_drmid_flashaccess": validate.text,
                "content_info": validate.all (
                    {
                        "package_label": validate.all (
                            {
                                "value": validate.text
                            })
                    })
            }])
    }
)
_media_schema = validate.Schema (
    validate.any (
        None,
        { "hls": validate.text },
        { "hds": validate.text },
        {
            "hls": validate.text,
            "hds": validate.text
        }
    )
)
_geo_schema = validate.Schema (
    {
        "countryCode": validate.text
    },
    validate.get ("countryCode")
)
# ------------------

class Dplay (Plugin):
    @classmethod
    def can_handle_url (cls, url):
        return _url_re.match (url)

    # Returns true if stream is playable (i.e. non-premium & not drm-protected)
    def _is_playable (self, data):
        if data['data'][0]['video_metadata_drmid_playready'] != 'none':
            return False
        if data['data'][0]['video_metadata_drmid_playready'] != 'none':
            return False
        if data['data'][0]['content_info']['package_label']['value'] == 'Premium':
            return False
        return True

    # Parses streams
    def _create_streams (self, parser, stream):
        try:
            if stream['format'] == 'hds':
                streams = parser (self.session, stream['url'],
                                  params={'hdcore': '3.8.0'})
            else:
                streams = parser (self.session, stream['url'])
            return streams.items ()
        except IOError as err:
            self.logger.error ('Failed to extract {0} streams: {1}',
                               stream['format'].upper (), err)

    def _get_streams (self):
        # Set header data for user-agent
        hdr = {'User-Agent': USER_AGENT.format('sv_SE')}
        
        # Parse video ID from data received from supplied URL
        res = http.get (self.url, headers=hdr).text
        match = _videoid_re.search (res)
        if not match:
            return {}   # Return if shortlink/video ID not found
        videoId = match.group ('id')
        
        # Get data from general API to validate that stream is playable
        res = http.get (GENERAL_API_URL.format (videoId), headers=hdr)
        data = http.json (res, schema=_api_schema)
        if not data['data']:        # <-- May be better to log a proper error
            return {}
        if not self._is_playable (data):
            return {}
        
        # Get geo data, validate and form cookie consisting of
        # geo data + expiry timestamp (current time + 1 hour)
        res = http.get ('http://geo.dplay.se/geo.js', headers=hdr)
        geo = http.json (res, schema=_geo_schema)
        timestamp = (int (time.time ()) + 3600) * 1000
        cookie = 'dsc-geo=%s' % quote ('{"countryCode":"%s","expiry":%s}' % (geo, timestamp))
        
        # Append cookie to headers
        hdr['Cookie'] = cookie
        
        # Get available streams using stream API
        res = http.get (STREAM_API_URL.format (videoId, 'hls'), headers=hdr, verify=False)
        data = http.json (res, schema=_media_schema)
        media = data.copy ()
        res = http.get (STREAM_API_URL.format (videoId, 'hds'), headers=hdr, verify=False)
        data = http.json (res, schema=_media_schema)
        media.update (data)
        
        # Reformat data into list with stream format and url
        streams = [{'format': k, 'url': media[k]} for k in media]
        
        # Create mapper for supported stream types (HLS/HDS)
        mapper = StreamMapper (cmp=lambda type, video: video['format'] == type)
        mapper.map ('hls', self._create_streams, HLSStream.parse_variant_playlist)
        mapper.map ('hds', self._create_streams, HDSStream.parse_manifest)
        
        # Feed stream data to mapper and return all streams found
        return mapper (streams)

__plugin__ = Dplay

@@ -529,16 +529,103 @@
 /geo.js'
+%0ASWF_URL = 'http://player.dplay.se/4.3.5/swf/AkamaiAdvancedFlowplayerProvider_v3.8.swf'
 %0A%0A# User
@@ -2706,16 +2706,31 @@
 '3.8.0'%7D
+, pvswf=SWF_URL
 )%0A      

Add pvswf parameter to HDS stream parser