#@PydevCodeAnalysisIgnore
'''
@author Fabio Zadrozny
'''
IS_PYTHON3K = 0
try:
    import __builtin__
except ImportError:
    import builtins as __builtin__  # Python 3.0
    IS_PYTHON3K = 1

try:
    True
    False
except NameError:
    # If it's not defined, let's define it now.
    setattr(__builtin__, 'True', 1)  # Python 3.0 does not accept __builtin__.True = 1 in its syntax
    setattr(__builtin__, 'False', 0)

from pydevd_constants import IS_JYTHON

if IS_JYTHON:
    import java.lang
    SERVER_NAME = 'jycompletionserver'
    import _pydev_jy_imports_tipper  # as _pydev_imports_tipper #changed to be backward compatible with 1.5
    _pydev_imports_tipper = _pydev_jy_imports_tipper

else:
    # it is python
    SERVER_NAME = 'pycompletionserver'
    import _pydev_imports_tipper


from _pydev_imps import _pydev_socket as socket

import sys
if sys.platform == "darwin":
    # See: https://sourceforge.net/projects/pydev/forums/forum/293649/topic/3454227
    try:
        import _CF  # Don't fail if it doesn't work -- do it because it must be loaded on the main thread! @UnresolvedImport @UnusedImport
    except:
        pass


# initial sys.path
_sys_path = []
for p in sys.path:
    # changed to be compatible with 1.5
    _sys_path.append(p)

# initial sys.modules
_sys_modules = {}
for name, mod in sys.modules.items():
    _sys_modules[name] = mod


import traceback

from _pydev_imps import _pydev_time as time

try:
    import StringIO
except:
    import io as StringIO #Python 3.0

try:
    from urllib import quote_plus, unquote_plus
except ImportError:
    from urllib.parse import quote_plus, unquote_plus #Python 3.0

INFO1 = 1
INFO2 = 2
WARN = 4
ERROR = 8

DEBUG = INFO1 | ERROR

def dbg(s, prior):
    if prior & DEBUG != 0:
        sys.stdout.write('%s\n' % (s,))
#        f = open('c:/temp/test.txt', 'a')
#        print_ >> f, s
#        f.close()

import pydev_localhost
HOST = pydev_localhost.get_localhost() # Symbolic name meaning the local host

MSG_KILL_SERVER = '@@KILL_SERVER_END@@'
MSG_COMPLETIONS = '@@COMPLETIONS'
MSG_END = 'END@@'
MSG_INVALID_REQUEST = '@@INVALID_REQUEST'
MSG_JYTHON_INVALID_REQUEST = '@@JYTHON_INVALID_REQUEST'
MSG_CHANGE_DIR = '@@CHANGE_DIR:'
MSG_OK = '@@MSG_OK_END@@'
MSG_IMPORTS = '@@IMPORTS:'
MSG_PYTHONPATH = '@@PYTHONPATH_END@@'
MSG_CHANGE_PYTHONPATH = '@@CHANGE_PYTHONPATH:'
MSG_JEDI = '@@MSG_JEDI:'
MSG_SEARCH = '@@SEARCH'

BUFFER_SIZE = 1024



currDirModule = None

def CompleteFromDir(directory):
    '''
    This is necessary so that we get the imports from the same directory where the file
    we are completing is located.
    '''
    global currDirModule
    if currDirModule is not None:
        if len(sys.path) > 0 and sys.path[0] == currDirModule:
            del sys.path[0]

    currDirModule = directory
    sys.path.insert(0, directory)


def ChangePythonPath(pythonpath):
    '''Changes the pythonpath (clears all the previous pythonpath)

    @param pythonpath: string with paths separated by |
    '''

    split = pythonpath.split('|')
    sys.path = []
    for path in split:
        path = path.strip()
        if len(path) > 0:
            sys.path.append(path)


class Processor:

    def __init__(self):
        # nothing to do
        return

    def removeInvalidChars(self, msg):
        try:
            msg = str(msg)
        except UnicodeDecodeError:
            pass

        if msg:
            try:
                return quote_plus(msg)
            except:
                sys.stdout.write('error making quote plus in %s\n' % (msg,))
                raise
        return ' '

    def formatCompletionMessage(self, defFile, completionsList):
        '''
        Format the completions suggestions in the following format:
        @@COMPLETIONS(modFile(token,description),(token,description),(token,description))END@@
        '''
        compMsg = []
        compMsg.append('%s' % defFile)
        for tup in completionsList:
            compMsg.append(',')

            compMsg.append('(')
            compMsg.append(str(self.removeInvalidChars(tup[0])))  # token
            compMsg.append(',')
            compMsg.append(self.removeInvalidChars(tup[1]))  # description

            if(len(tup) > 2):
                compMsg.append(',')
                compMsg.append(self.removeInvalidChars(tup[2]))  # args - only if function.

            if(len(tup) > 3):
                compMsg.append(',')
                compMsg.append(self.removeInvalidChars(tup[3]))  # TYPE

            compMsg.append(')')

        return '%s(%s)%s' % (MSG_COMPLETIONS, ''.join(compMsg), MSG_END)

class Exit(Exception):
    pass

class CompletionServer:

    def __init__(self, port):
        self.ended = False
        self.port = port
        self.socket = None  # socket to send messages.
        self.exit_process_on_kill = True
        self.processor = Processor()


    def connectToServer(self):
        from _pydev_imps import _pydev_socket as socket

        self.socket = s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect((HOST, self.port))
        except:
            sys.stderr.write('Error on connectToServer with parameters: host: %s port: %s\n' % (HOST, self.port))
            raise

    def getCompletionsMessage(self, defFile, completionsList):
        '''
        get message with completions.
        '''
        return self.processor.formatCompletionMessage(defFile, completionsList)

    def getTokenAndData(self, data):
        '''
        When we receive this, we have 'token):data'
        '''
        token = ''
        for c in data:
            if c != ')':
                token = token + c
            else:
                break;

        return token, data.lstrip(token + '):')

    def emulated_sendall(self, msg):
        MSGLEN = 1024 * 20

        totalsent = 0
        while totalsent < MSGLEN:
            sent = self.socket.send(msg[totalsent:])
            if sent == 0:
                return
            totalsent = totalsent + sent


    def send(self, msg):
        if not hasattr(self.socket, 'sendall'):
            #Older versions (jython 2.1)
            self.emulated_sendall(msg)
        else:
            if IS_PYTHON3K:
                self.socket.sendall(bytearray(msg, 'utf-8'))
            else:
                self.socket.sendall(msg)


    def run(self):
        # Echo server program
        try:
            import _pydev_log
            log = _pydev_log.Log()

            dbg(SERVER_NAME + ' connecting to java server on %s (%s)' % (HOST, self.port) , INFO1)
            # after being connected, create a socket as a client.
            self.connectToServer()

            dbg(SERVER_NAME + ' Connected to java server', INFO1)


            while not self.ended:
                data = ''

                while data.find(MSG_END) == -1:
                    received = self.socket.recv(BUFFER_SIZE)
                    if len(received) == 0:
                        raise Exit()  # ok, connection ended
                    if IS_PYTHON3K:
                        data = data + received.decode('utf-8')
                    else:
                        data = data + received

                try:
                    try:
                        if data.find(MSG_KILL_SERVER) != -1:
                            dbg(SERVER_NAME + ' kill message received', INFO1)
                            # break if we received kill message.
                            self.ended = True
                            raise Exit()

                        dbg(SERVER_NAME + ' starting keep alive thread', INFO2)

                        if data.find(MSG_PYTHONPATH) != -1:
                            comps = []
                            for p in _sys_path:
                                comps.append((p, ' '))
                            self.send(self.getCompletionsMessage(None, comps))

                        else:
                            data = data[:data.rfind(MSG_END)]

                            if data.startswith(MSG_IMPORTS):
                                data = data[len(MSG_IMPORTS):]
                                data = unquote_plus(data)
                                defFile, comps = _pydev_imports_tipper.GenerateTip(data, log)
                                self.send(self.getCompletionsMessage(defFile, comps))

                            elif data.startswith(MSG_CHANGE_PYTHONPATH):
                                data = data[len(MSG_CHANGE_PYTHONPATH):]
                                data = unquote_plus(data)
                                ChangePythonPath(data)
                                self.send(MSG_OK)

                            elif data.startswith(MSG_JEDI):
                                data = data[len(MSG_JEDI):]
                                data = unquote_plus(data)
                                line, column, encoding, path, source = data.split('|', 4)
                                try:
                                    import jedi  # @UnresolvedImport
                                except:
                                    self.send(self.getCompletionsMessage(None, [('Error on import jedi', 'Error importing jedi', '')]))
                                else:
                                    script = jedi.Script(
                                        # Line +1 because it expects lines 1-based (and col 0-based)
                                        source=source,
                                        line=int(line) + 1,
                                        column=int(column),
                                        source_encoding=encoding,
                                        path=path,
                                    )
                                    lst = []
                                    for completion in script.completions():
                                        t = completion.type
                                        if t == 'class':
                                            t = '1'

                                        elif t == 'function':
                                            t = '2'

                                        elif t == 'import':
                                            t = '0'

                                        elif t == 'keyword':
                                            continue  # Keywords are already handled in PyDev

                                        elif t == 'statement':
                                            t = '3'

                                        else:
                                            t = '-1'

                                        # gen list(tuple(name, doc, args, type))
                                        lst.append((completion.name, '', '', t))
                                    self.send(self.getCompletionsMessage('empty', lst))

                            elif data.startswith(MSG_SEARCH):
                                data = data[len(MSG_SEARCH):]
                                data = unquote_plus(data)
                                (f, line, col), foundAs = _pydev_imports_tipper.Search(data)
                                self.send(self.getCompletionsMessage(f, [(line, col, foundAs)]))

                            elif data.startswith(MSG_CHANGE_DIR):
                                data = data[len(MSG_CHANGE_DIR):]
                                data = unquote_plus(data)
                                CompleteFromDir(data)
                                self.send(MSG_OK)

                            else:
                                self.send(MSG_INVALID_REQUEST)
                    except Exit:
                        self.send(self.getCompletionsMessage(None, [('Exit:', 'SystemExit', '')]))
                        raise

                    except:
                        dbg(SERVER_NAME + ' exception occurred', ERROR)
                        s = StringIO.StringIO()
                        traceback.print_exc(file=s)

                        err = s.getvalue()
                        dbg(SERVER_NAME + ' received error: ' + str(err), ERROR)
                        self.send(self.getCompletionsMessage(None, [('ERROR:', '%s\nLog:%s' % (err, log.GetContents()), '')]))


                finally:
                    log.Clear()

            self.socket.close()
            self.ended = True
            raise Exit()  # connection broken


        except Exit:
            if self.exit_process_on_kill:
                sys.exit(0)
            # No need to log SystemExit error
        except:
            s = StringIO.StringIO()
            exc_info = sys.exc_info()

            traceback.print_exception(exc_info[0], exc_info[1], exc_info[2], limit=None, file=s)
            err = s.getvalue()
            dbg(SERVER_NAME + ' received error: ' + str(err), ERROR)
            raise



if __name__ == '__main__':

    port = int(sys.argv[1])  # this is from where we want to receive messages.

    t = CompletionServer(port)
    dbg(SERVER_NAME + ' will start', INFO1)
    t.run()
