#!python
import os
import begin
from pyftpdlib.handlers import TLS_FTPHandler
from pyftpdlib.servers import MultiprocessFTPServer as FTPServer
from fstpy.authorizers import DummyAuthorizer, MD5Authorizer
from fstpy.filesystems import AbstractedFS



def Pub_TLS_FTPHandler_Factory(port):
    import zmq

    context = zmq.Context()
    socket = context.socket(zmq.PUB)
    socket.bind("tcp://*:{0}".format(port))

    class Pub_TLS_FTPHandler(TLS_FTPHandler):



        def on_connect(self):
            print ("{0}:{1} connected".format(self.remote_ip, self.remote_port))

        def on_disconnect(self):
            # do something when client disconnects
            pass

        def on_login(self, username):
            # do something when user login
            pass

        def on_logout(self, username):
            # do something when user logs out
            pass

        def on_file_sent(self, file):
            # do something when a file has been sent
            pass

        def on_file_received(self, file):
            # do something when a file has been received
            print('Received: {0}'.format(file))
            channel = file.split('/')[1]
            socket.send_string('{0} {1}'.format(channel, file))
            pass

        def on_incomplete_file_sent(self, file):
            # do something when a file is partially sent
            pass

        def on_incomplete_file_received(self, file):
            # remove partially uploaded files
            #import os
            #os.remove(file)
            pass
    
    return Pub_TLS_FTPHandler

@begin.start
@begin.convert(port=int, passive_ports_lower=int, passive_ports_upper=int)
def main(fs, address=os.getenv('FSTPY_HOST', ''), port=os.getenv('FSTPY_PORT', 2121),
             masquerade=os.getenv('FSTPY_MASQUERADE', None),
             passive_ports_lower=os.getenv('FSTPY_PASSIVE_LOWER', 60200),
             passive_ports_upper=os.getenv('FSTPY_PASSIVE_UPPER', 60210),
             credentials=os.getenv('FSTPY_CREDENTIALS', 'credentials.txt'), 
             keyfile=os.getenv('FSTPY_KEYFILE', 'server.key'), 
             crtfile=os.getenv('FSTPY_CRTFILE', 'server.crt'),
             pubport=os.getenv('FSTPY_PUBPORT', None),
             banner=os.getenv('FSTPY_BANNER', 'FsTPy based ftpd ready.')):
    # Instantiate a dummy authorizer for managing 'virtual' users
    authorizer = MD5Authorizer(fs, credentials)

    
    # Define a new user having full r/w permissions and a read-only
    # anonymous user
    #authorizer.add_user('user', '***', '/' , perm='elradfmwMT')
    #authorizer.add_anonymous(os.getcwd())

    # Instantiate FTP handler class
    handler = Pub_TLS_FTPHandler_Factory(pubport) if pubport else TLS_FTPHandler
    handler.abstracted_fs = AbstractedFS
    handler.certfile =  crtfile
    handler.keyfile = keyfile
    handler.authorizer = authorizer

    # Define a customized banner (string returned when client connects)
    handler.banner = banner

    # Specify a masquerade address and the range of ports to use for
    # passive connections.  Decomment in case you're behind a NAT.
    if masquerade:
        handler.masquerade_address = masquerade
    handler.passive_ports = range(passive_ports_lower, passive_ports_upper)

    # Instantiate FTP server class and listen on address:port
    server_address = (address, port)
    server = FTPServer(server_address, handler)

    # set a limit for connections
    server.max_cons = 512 
    server.max_cons_per_ip = 25

    # start ftp server
    server.serve_forever()

