#// Copyright (c) 2000-2017 Ericsson Telecom AB                                                         //
#// All rights reserved. This program and the accompanying materials are made available under the terms //
#// of the Eclipse Public License v1.0 which accompanies this distribution, and is available at         //
#// http://www.eclipse.org/legal/epl-v10.html                                                           //
#/////////////////////////////////////////////////////////////////////////////////////////////////////////
import sys, json, threading, urllib2, time, logging, re, cookielib, ssl

class ScheduledPlaylist:

    def __init__(self, descriptor, customCallbackForResponse = None):
        self._logger = logging.getLogger(__name__)
        self._status = {'node': {'val': '', 'tp': 11}}
        self._finished = 0
        self._descriptor = descriptor
        self._callback = customCallbackForResponse
        self._stopEvent = threading.Event()
        self._continueEvent = threading.Event()
        self._continueEvent.set()
        self._urlOpeners = []
        self._threads = []

    def _waitOrExit(self):
        if self._stopEvent.isSet():
            return True
        self._continueEvent.wait()
        if self._stopEvent.isSet():
            return True
        else:
            return False

    def _wait(self, amount):
        time.sleep(amount)

    def _checkCondition(self, url, opener, expression):
        requests = [
            {
                'getData': {
                    'source': 'DataSource',
                    'element': 'Sources',
                    'filter': expression
                }
            }
        ]
        response = self._sendRequestsToUrl(opener, url, requests)
        if 'node' in response['contentList'][0] and response['contentList'][0]['node']['tp'] == 0:
            return False
        else:
            return True

    def _sendRequestsToUrl(self, opener, url, requests):
        return json.loads(opener.open(urllib2.Request(url, json.dumps({'requests': requests}))).read())

    def _sendRequests(self, url, opener, requests):
        if len(requests) > 0:
            if 'getData' in requests[0]:
                self._status['node']['val'] = '[led:green]Running - Last action: ' + requests[0]['getData']['element']
            elif 'setData' in requests[0]:
                self._status['node']['val'] = '[led:green]Running - Last action: ' + requests[0]['setData']['element']
        return self._sendRequestsToUrl(opener, url, requests)

    def _processPlaylist(self, url, opener, action):
        try:
            if 'condition' in action and 'expression' in action['condition']:
                tries = 0
                startTime = time.time()
                while True:
                    if self._waitOrExit():
                        return
                    self._continueEvent.wait()
                    tries += 1
                    if self._checkCondition(url, opener, action['condition']['expression']):
                        break
                    elif ('cancelingTimeout' in action['condition'] and time.time() - startTime > action['condition']['cancelingTimeout']) or ('numberOfExecutions' in action['condition'] and tries > action['condition']['numberOfExecutions']):
                        self.stop()
                        self._status['node']['val'] = '[led:red]Timeout'
                        return
                    if 'evaluatingPeriod' in action['condition']:
                        self._wait(action['condition']['evaluatingPeriod'])
            if 'startTime' in action:
                self._wait(action['startTime'])
            if self._waitOrExit():
                return
            response = self._sendRequests(url, opener, action['requests'])
            if self._waitOrExit():
                return
            self._playlistFinished(action['id'])
            if self._callback is not None:
                self._callback(response)

        except:
            self._logger.exception('Error during playlist execution')
            self.stop()
            self._status['node']['val'] = '[led:red]Error'

    def _playlistFinished(self, id):
        self._finished += 1
        if self._finished == len(self._threads):
            self._status['node']['val'] = self._status['node']['val'].replace('[led:green]Running', '[led:blue]Finished')
            self._logout()
        if id is not None:
            for thread in self._threads:
                if 'relativeTo' in thread and id in thread['relativeTo']:
                    thread['relativeTo'].remove(id)
                    if len(thread['relativeTo']) == 0:
                        thread['thread'].start()

    def _getBaseUrl(self, url):
        match = re.search(r'\w/', url)
        if match:
            return url[:match.start() + 1]
        else:
            return url

    def _logout(self):
        for url, opener in self._urlOpeners:
            opener.open(urllib2.Request(self._getBaseUrl(url) + '/logout/api.authenticate'))

    def _login(self, opener, url, userCredentials):
        try:
            opener.open(urllib2.Request(self._getBaseUrl(url) + '/login/api.authenticate', '{"username": "' + userCredentials['username'] + '", "password": "' + userCredentials['password'] + '"}'))
            self._urlOpeners.append((url, opener))
        except:
            pass

    def start(self, userCredentials):
        for playlistObject in self._descriptor:
            url = playlistObject['apiUrl']
            try:
                opener = urllib2.build_opener(urllib2.HTTPHandler(), urllib2.HTTPSHandler(context = ssl._create_unverified_context()), urllib2.HTTPCookieProcessor(cookielib.CookieJar()), urllib2.ProxyHandler({}))
            except:
                opener = urllib2.build_opener(urllib2.HTTPHandler(), urllib2.HTTPSHandler(), urllib2.HTTPCookieProcessor(cookielib.CookieJar()), urllib2.ProxyHandler({}))
            if userCredentials['username'] is not None and userCredentials['password'] is not None:
                self._login(opener, url, userCredentials)
            playlist = playlistObject['playlist']
            for action in playlist:
                if 'id' not in action:
                    action['id'] = None
                requests = action['requests']
                thread = threading.Thread(target = self._processPlaylist, args = (url, opener, action))
                thread.daemon = True
                self._threads.append({'thread': thread})
                if 'relativeTo' not in action or len(action['relativeTo']) == 0:
                    thread.start()
                else:
                    self._threads[-1]['relativeTo'] = action['relativeTo']
        if len(self._threads) == 0:
            self._status['node']['val'] = '[led:blue]Finished'
        else:
            self._status['node']['val'] = '[led:green]Running'

    def stop(self):
        self._stopEvent.set()
        self._continueEvent.set()
        self._status['node']['val'] = '[led:black]Stopped'
        self._logout()

    def pause(self):
        if self._continueEvent.isSet():
            self._continueEvent.clear()
            self._status['node']['val'] = self._status['node']['val'].replace('[led:green]Running', '[led:yellow]Paused')
        else:
            self._continueEvent.set()
            self._status['node']['val'] = self._status['node']['val'].replace('[led:yellow]Paused', '[led:green]Running')

    def isRunning(self):
        for thread in self._threads:
            if thread['thread'].isAlive():
                return True
        return False

    def getStatus(self):
        return self._status

if __name__ == '__main__':
    def printResponse(response):
        print json.dumps(response)

    playlistDescriptor = []
    with open(sys.argv[1], 'r') as f:
        playlistDescriptor = json.load(f)
    scheduledPlaylist = ScheduledPlaylist(playlistDescriptor, printResponse)
    scheduledPlaylist.start({'username': 'admin', 'password': 'admin', 'groups': set(['admin'])})
    time.sleep(3)
    while scheduledPlaylist.isRunning():
        time.sleep(1)