#// 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                                                           //
#/////////////////////////////////////////////////////////////////////////////////////////////////////////
#!/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__':

    # Initialize logging facility
    logConfigPath = 'LogConfig.json'
    if os.path.exists(logConfigPath):
        with open(logConfigPath, 'r') as f:
            logConfig = json.load(f)
        logging.config.dictConfig(logConfig)
    else:
        logging.basicConfig(level="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
    # Logging facility initialization done

    directory = os.path.abspath(os.path.dirname(sys.argv[0]))

    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'])
