#! /usr/bin/env python
# -*- coding: utf8 -*-

"""
Copyright (C) 2007 Adolfo González Blázquez <code@infinicode.org>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version. 

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. 

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

If you find any bugs or have any suggestions email: code@infinicode.org
"""

from message import *
from codes import Codes
from protocol import Protocol

import socket
import time
import sys
import user

class DonkeyStats:

        def __init__(self, gui, debug=True):

                # Globals
                self.reconnect_timeout = 30
                self.keep = True
                self.logged = False
                self.debug = debug

                self.stats = []
                self.downloadingfiles = 0

                # GUI object
                self.gui = gui

                # Protocol handler
                self.p = Protocol(self.debug)
                if self.gui != None: self.p.set_connection_data(self.gui.prefs.get_host(),
                                                                        self.gui.prefs.get_port(),
                                                                        self.gui.prefs.get_login(),
                                                                        self.gui.prefs.get_password())
                try:
                        # Try to connect
                        self.connect_loop()

                        # Try to read messages
                        self.message_loop()
                except KeyboardInterrupt:
                        if self.debug: print "[C] Bye!"
                        self.p.close_connection()
                        sys.exit(0)

                if self.debug: print "[C] Bye!"
                self.p.close_connection()


        def reconnect(self):
                if self.debug: print "[C] Reconnecting..."
                self.p.close_connection()
                self.logged = False
                if self.gui != None:
                        self.gui.reconnect = False
                        self.p.set_connection_data(self.gui.prefs.get_host(),
                                                                        self.gui.prefs.get_port(),
                                                                        self.gui.prefs.get_login(),
                                                                        self.gui.prefs.get_password())
                time.sleep(2)
                self.connect_loop()
                self.message_loop()


        def connect_loop(self):
                self.socket = None
                #if self.gui != None: self.gui.show_icon(False)
                if self.gui != None:
                                self.gui.set_icon_error()
                                self.gui.set_text_error("Not connected!")
                while self.socket == None or self.socket == '' and self.keep:
                        if self.gui != None: self.keep = self.gui.get_keep()
                        self.socket = self.p.open_connection()
                        if self.socket == '':
                                if self.debug: print "[C] Waiting " + str(self.reconnect_timeout) + " to  reconnect..."
                                time.sleep(self.reconnect_timeout)
                if self.debug: print "[C] Connected!"
                if self.gui != None: self.gui.show_icon(True)


        def message_loop(self):
                while self.keep:
                        self.get_message()
                        if self.gui != None: self.keep = self.gui.get_keep()
                        if self.gui != None and self.gui.get_reconnect(): self.reconnect()


        # Get one message header and process it
        def get_message(self):
                m = None
                try:
                        m = MessageReader(self.socket)
                        self.parse_message(m)
                except socket.timeout, e:
                        if self.debug: print "  ERROR: Connection with server timed out!"
                        self.p.close_connection()
                        self.logged = False
                        self.connect_loop()
                        self.message_loop()
                except KeyboardInterrupt, e:
                        if self.debug: print "[C] Bye!"
                        self.p.close_connection()
                        self.logged = False
                        self.keep = False
                        sys.exit(0)
                except Exception, e:
                        if self.debug:
                                print " ERROR: ", m.get_name()
                                print " ", e
                                print " ", repr(m.data)
                                file = open(user.home+'/error_mlicon.txt', 'a')
                                file.write(m.get_name())
                                file.write(str(e)+"\n")
                                file.write(repr(m.data)+"\n")
                                file.write("\n")


        # Process messages
        def parse_message(self, m):
                if m.code == Codes.server['CoreProtocol'] and not self.logged:
                        self.p.server_coreprotocol(m)
                        self.p.client_protocolversion()
                        self.p.client_pollmode(True)
                        self.p.client_password()
                        self.logged = True
                elif m.code == Codes.server['BadPassword']:
                        self.p.server_badpassword()
                        if self.debug: print "[C] Bye!"
                        self.p.close_connection()
                        if self.gui != None:
                                self.gui.set_icon_error()
                                self.gui.set_text_error("Bad password!")
                        sys.exit(0)
                elif m.code == Codes.server['NetworkInfo']:
                        self.p.server_networkinfo(m)
                elif m.code == Codes.server['ConsoleMessage']:
                        self.p.server_consolemessage(m)
                elif m.code == Codes.server['ClientStats']:
                        self.stats = self.p.server_clientstats(m)
                        #self.p.client_getdownloadingfiles()
                #elif m.code == Codes.server['DownloadingFiles']:
                        #self.downloadingfiles = self.p.server_downloadingfiles(m)
                        #pass
                #elif m.code == Codes.server['OptionsInfo']:
                        #self.p.server_optionsinfo(m)
                        #pass
                else: pass

                # Send data to gui icon
                if self.gui != None and len(self.stats) > 0:
                                self.stats[3] = self.downloadingfiles
                                self.gui.set_stats_text(self.stats)
                                self.gui.set_icon(self.stats)



if __name__ == "__main__":
        DonkeyStats(None)