#!/usr/bin/env python
#
# Copyright (c) 2013 Big Switch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
#      http://www.eclipse.org/legal/epl-v10.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied. See the License for the specific language governing
# permissions and limitations under the License.
#

import sys
from threading import currentThread
from SocketServer import BaseRequestHandler, TCPServer
from code import InteractiveConsole

_locals = None

class DebugLogger(object):
    def do_print(self, *args):
        for i in args:
            print i,
        print
    info = do_print
    warn = do_print
    debug = do_print
_log = DebugLogger()


class DebugConsole(InteractiveConsole):
    def __init__(self, request):
        self.request = request
        InteractiveConsole.__init__(self, _locals)

    def raw_input(self, prompt):
        self.request.send(prompt)
        data = self.request.recv(10000).rstrip()
        if len(data) == 1 and ord(data[0]) == 4:
            sys.exit()
        return data

    def write(self, data):
        self.request.send(str(data))

    def write_nl(self, data):
        self.write(str(data)+"\r\n")

class DebugServerHandler(BaseRequestHandler):
    def __init__(self, request, client_address, server):
        currentThread()._thread.setName("debugserver-%s:%d" % client_address)
        _log.debug('Open connection to DebugServer from %s:%d' % client_address)
        BaseRequestHandler.__init__(self, request, client_address, server)

    def handle(self):
        console = DebugConsole(self.request)
        sys.displayhook = console.write_nl
        console.interact('DebugServer')
        self.request.close()

class DebugServer(TCPServer):
    daemon_threads = True
    allow_reuse_address = True

    def handle_error(self, request, client_address):
        _log.debug('Closing connection to DebugServer from %s:%d' % client_address)
        request.close()

def run_server(port=6655, host='0.0.0.0', locals=locals()):
    currentThread()._thread.setName("debugserver-main")

    global _locals
    _locals = locals
    if "log" in locals.keys():
        global _log
        _log = locals["log"]

    _log.info("Starting DebugServer on port %d" % port)
    server = DebugServer(('', port), DebugServerHandler)
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass

if __name__ == "__main__":
    run_server()
