#// Copyright (c) 2000-2018 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:
                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')
                # load service module
                module = importlib.import_module(appName)
                # create the handler
                handler = module.createHandler(appPath)
                server.requestHandlers[module.EXTENSION] = handler
                # 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'])
