#// 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 v2.0 which accompanies this distribution, and is available at         //
#// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html                                                           //
#/////////////////////////////////////////////////////////////////////////////////////////////////////////
#!/usr/bin/python

'''
The main module of the framework.
AppAgent is an http server, which redirects http messages based on the message's uri extension to 
microservices loaded dynamically from the src/Microservices directory. The microservices are handling the 
application specific http requests by implementing the message handler interface.
An application based on this framework should contain the framework files, along with application specific 
microservices located in the src/Microservices directory.
The DataSource handler is always present, and can be used by all microservices that handle DsRestAPI requests.
For more details on the microservice- and message handler interface, see the comments for the microservices 
(src/Microservices/__init__.py).
'''

import threading, errno, os, sys, shutil, json, traceback, urllib2, logging, logging.config, ssl, importlib
from BaseHTTPServer import HTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler
from SocketServer import ThreadingMixIn

class FileHandler(SimpleHTTPRequestHandler):
    '''A file handler that supports the methods needed by the framework'''

    def _handleProxyRequests(self, method, userCredentials):
        if userCredentials['username'] is not None:
            parts = self._cleanPath(self.path).split('/', 2)
            url = parts[1].decode('hex')
            if len(parts) > 2:
                url = url + '/' + parts[2]
            body = None
            if method == 'POST' or method == 'PUT':
                body = self.rfile.read(int(self.headers.getheader('content-length')))
            try:
                request = urllib2.Request(url, body, self.headers)
                request.get_method = lambda: method
                response = urllib2.urlopen(request)
                self.send_response(200)
                headers = response.info()
                for header in headers:
                    self.send_header(header, headers[header])
                self.end_headers()
                self.wfile.write(response.read())
            except urllib2.HTTPError as e:
                self.send_response(e.code)
                self.end_headers()
            except Exception as e:
                self.send_response(404)
                self.end_headers()
        else:
            self.send_response(401)
            self.end_headers()

    def _lsdir(self, path):
        if path == '':
            path = '.'
        result = []
        try:
            files = os.listdir(path)
            for file in files:
                fileName = path + '/' + file
                contentType = ''
                if os.path.islink(fileName):
                    contentType += 'l'
                else:
                    contentType += '-'
                if os.path.isdir(fileName):
                    contentType += 'd'
                else:
                    contentType += 'f'
                stat = os.stat(fileName)
                result.append({
                    'fileName': fileName,
                    'contentType': contentType,
                    'size': stat.st_size,
                    'timestamp': stat.st_mtime
                })
        except:
            pass
        return {'fileList': result}

    def _mkdir(self, path):
        try:
            os.makedirs(path)
            return True
        except OSError as e:
            if e.errno == errno.EEXIST and os.path.isdir(path):
                pass
            else:
                return False

    def _rmdir(self, path):
        try:
            if not os.path.exists(path):
                return
            if os.path.isfile(path) or os.path.islink(path):
                os.unlink(path)
            else:
                shutil.rmtree(path)
            return True
        except:
            return False

    def _cleanPath(self, path):
        return path.strip('/')

    def do_LSDIR(self):
        '''Listing the contents of a directory'''
        path = self._cleanPath(self.path)
        if path.startswith('proxy'):
            self._handleProxyRequests('LSDIR', self.server.getUserCredentials(self.headers))
        else:
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(json.dumps(self._lsdir(path), indent = 4))

    def do_RMDIR(self):
        '''Deleting directory'''
        userCredentials = self.server.getUserCredentials(self.headers)
        if userCredentials['username'] is not None:
            path = self._cleanPath(self.path)
            if path.startswith('proxy'):
                self._handleProxyRequests('RMDIR', userCredentials)
            else:
                if self._rmdir(path):
                    self.send_response(200)
                else:
                    self.send_response(401)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
        else:
            self.send_response(401)
            self.end_headers()

    def do_MKDIR(self):
        '''Creating a directory'''
        userCredentials = self.server.getUserCredentials(self.headers)
        if userCredentials['username'] is not None:
            path = self._cleanPath(self.path)
            if path.startswith('proxy'):
                self._handleProxyRequests('MKDIR', userCredentials)
            else:
                if self._mkdir(path):
                    self.send_response(200)
                else:
                    self.send_response(401)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
        else:
            self.send_response(401)
            self.end_headers()

    def do_PUT(self):
        '''Saving a file'''
        userCredentials = self.server.getUserCredentials(self.headers)
        if userCredentials['username'] is not None:
            path = self._cleanPath(self.path)
            if path.startswith('proxy'):
                self._handleProxyRequests('PUT', userCredentials)
            else:
                try:
                    with open(path, 'w') as f:
                        f.write(self.rfile.read(int(self.headers.getheader('content-length'))))
                    self.send_response(200)
                except:
                    self.send_response(401)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
        else:
            self.send_response(401)
            self.end_headers()

class MainHandler(FileHandler):
    '''The main handler of the HTTP server'''

    def _useHandlers(self, method, path, headers, body, userCredentials):
        '''Try to find a handler based on the extension and handle the request'''
        try:
            pathForExtension = path.split('?')[0]
            if '/' in pathForExtension:
                extension = pathForExtension[pathForExtension.rindex('/') + 1:]
            else:
                extension = pathForExtension
            handler = self.server.requestHandlers[extension]
            response = {
                'returnCode': 200,
                'mimeType': 'text/plain',
                'body': '',
                'headers': {}
            }
            handler.handleMessage(method, path, headers, body, userCredentials, response)
            self.send_response(response['returnCode'])
            if 'Content-Type' not in response['headers']:
                self.send_header('Content-Type', 'text/plain')
            for header in response['headers']:
                self.send_header(header, response['headers'][header])
            self.end_headers()
            self.wfile.write(response['body'])
            return True
        except:
            return False

    def do_GET(self):
        '''Handler GET requests'''
        path = self._cleanPath(self.path)
        if path.startswith('proxy'):
            self._handleProxyRequests('GET', self.server.getUserCredentials(self.headers))
        else:
            if not self._useHandlers('GET', path, self.headers, '', self.server.getUserCredentials(self.headers)):
                SimpleHTTPRequestHandler.do_GET(self)

    def do_POST(self):
        '''Handler POST requests'''
        userCredentials = self.server.getUserCredentials(self.headers)
        path = self._cleanPath(self.path)
        if path.startswith('proxy'):
            self._handleProxyRequests('POST', userCredentials)
        else:
            if not self._useHandlers('POST', path, self.headers, self.rfile.read(int(self.headers.getheader('content-length'))), userCredentials):
                self.send_response(404)
                self.send_header('Content-Type', 'text/plain')
                self.end_headers()
                self.wfile.write(self.path)

    def log_message(self, format, *args):
        '''Disables logging'''
        return

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    '''HTTP server that handles requests in a separate thread.'''

def runAppAgent(server, directory, htdocs, ssl, appList = None):

    logger = logging.getLogger('AppAgent')

    sys.path.insert(0, directory)

    server.requestHandlers = {}
    dsRestApiHandlers = {}

    guiDirectory = os.path.normpath(os.path.join(directory, htdocs))
    webAppDirectory = os.path.join(guiDirectory, 'WebApplications')
    customizationDirectory = os.path.join(guiDirectory, 'CustomizableContent')
    createdLinks = set()

    originalDirectory = os.getcwd()
    os.chdir(guiDirectory)

    microservicesDirectory = os.path.join(directory, 'Microservices')
    if appList is None:
        appList = os.listdir(microservicesDirectory)
    for app in appList:
        appPath = os.path.join(microservicesDirectory, app)
        if os.path.isdir(appPath):
            appName = 'Microservices.' + app
            try:
                module = importlib.import_module(appName)
                # create the handler
                handler = module.createHandler(appPath)
                server.requestHandlers[module.EXTENSION] = handler
                appWebAppDir = os.path.join(appPath, 'WebApplication')
                appGuiDir = os.path.join(appPath, 'GUI')
                # link webapp
                if os.path.isdir(appWebAppDir):
                    linkFile = os.path.join(webAppDirectory, app)
                    createdLinks.add(linkFile)
                    if not os.path.exists(linkFile):
                        os.symlink(os.path.relpath(appWebAppDir, webAppDirectory), linkFile)
                        logger.info('Linked WebApp: ' + os.path.relpath(appWebAppDir, webAppDirectory) + ' -> ' + linkFile)
                    else:
                        logger.warning('Linked WebApp: ' + app + ' already exists')
                # link customization
                if os.path.isdir(appGuiDir):
                    linkFile = os.path.join(customizationDirectory, app)
                    createdLinks.add(linkFile)
                    if not os.path.exists(linkFile):
                        os.symlink(os.path.relpath(appGuiDir, customizationDirectory), linkFile)
                        logger.info('Linked GUI: ' + os.path.relpath(appGuiDir, customizationDirectory) + ' -> ' + linkFile)
                    else:
                        logger.warning('Linked GUI: ' + app + ' already exists')
                # add DataSource handlers if they exist
                if hasattr(handler, 'getDataSourceHandlers'):
                    dsRestApiHandlers.update(handler.getDataSourceHandlers())
                logger.info('Loaded ' + appName + ' serving ' + module.EXTENSION)
            except Exception as e:
                logger.exception('Loading ' + appName + ' failed')

    # special microservice logic
    if 'api.authenticate' in server.requestHandlers:
        server.getUserCredentials = server.requestHandlers['api.authenticate'].getUserCredentials
    else:
        server.getUserCredentials = lambda headers: {'username': None, 'password': None, 'groups': set()}
    if 'api.appagent' in server.requestHandlers:
        server.requestHandlers['api.appagent'].setHandlers(dsRestApiHandlers)

    try:
        if ssl:
            server.socket = ssl.wrap_socket(server.socket, keyfile=os.path.join(directory, 'localhost.key'), certfile=os.path.join(directory, 'localhost.crt'), server_side=True)
        logger.info('Server started on ' + server.server_name + ':' + str(server.server_port) + ' serving directory: ' + os.getcwd())
        server.serve_forever()
    except:
        pass
    finally:
        logger.info('Stopping server')
        for handler in server.requestHandlers:
            server.requestHandlers[handler].close()
            logger.info("Handler closed: " + handler)
        os.chdir(directory)
        for link in createdLinks:
            if os.path.exists(link):
                os.unlink(link)
                logger.info('GUI unlinked: ' + link)
        os.chdir(originalDirectory)
        logger.info("Server stopped")

if __name__ == '__main__':
    directory = os.path.abspath(os.path.dirname(sys.argv[0]))

    # Initialize logging facility
    logConfigPath = os.path.join(directory, 'LogConfig.json')
    if os.path.exists(logConfigPath):
        with open(logConfigPath, 'r') as f:
            logConfig = json.load(f)
        logging.config.dictConfig(logConfig)
    else:
        logging.basicConfig()
    # Logging facility initialization done

    config = {}
    with open(os.path.join(directory, 'config.json'), 'r') as f:
        config = json.load(f)

    server = ThreadedHTTPServer((config['address'], config['port']), MainHandler)
    runAppAgent(server, directory, config['htdocs'], 'ssl' in config and config['ssl'])
