# -*- coding:utf-8 -*-
# addwindow.py
# Copyright (C) 2008-2009 Stefan J. Betz <stefan_betz@gmx.net>
#
# 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 3 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, see <http://www.gnu.org/licenses/>.

import pygtk
pygtk.require("2.0")
import gtk
from re import compile
from socket import gethostbyname, gethostbyaddr, gaierror as socketerror, herror as hosterror
from gettext import gettext
from pyneighborhood import db, dblock
from pyneighborhood.misc import sharepath, push_notification
from pyneighborhood.nmblookup import lookup, query_workgroup, query_host
from pyneighborhood.smbclient import scan_shares

_ = gettext

class AddWindow(object):
    """
    Add-dialog
    """

    def __init__(self, mainwindow):
        """
        Constructor
        """
        self.mainwindow = mainwindow
        self.xml = gtk.Builder()
        self.xml.set_translation_domain('pyNeighborhood')
        self.xml.add_from_file(sharepath('ui/addwindow.glade'))
        self.xml.connect_signals(self)
        
        self.window = self.xml.get_object("addwindow")
        self.status = self.xml.get_object("status")
        self.url = self.xml.get_object("urlentry")
        # RE for the URL Entry:
        # Group 1 = host or IP
        # Group 2 = share
        self.urlre = compile("^//(.*)/(.*)$")
        self.hostonlyre = compile("^//(.*)$")
        self.ipre = compile("^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$")

    def response_handler(self, widget, response_id):
        """
        Response Handler
        """
        if response_id == gtk.RESPONSE_CANCEL:
            self.window.destroy()
            return False
        elif response_id == gtk.RESPONSE_OK:
            # RE the url...
            url = self.urlre.match(self.url.get_text())
            if url != None:
                if self.ipre.match(url.group(1)):
                    ip = url.group(1)
                    hostname = None
                else:
                    hostname = url.group(1)
                    ip = None
                hostonly = False
            else:
                url = self.hostonlyre.match(self.url.get_text())
                if url != None:
                    if self.ipre.match(url.group(1)):
                        ip = url.group(1)
                        hostname = None
                    else:
                        hostname = url.group(1)
                        ip = None
                    hostonly = True
                else:
                    push_notification(_("Invalid URL specified!\n"),level=2)
                    self.window.destroy()
                    return True
            # Step 1: Resolve hostname (if any) to IP via DNS
            self.status.set_fraction(0.2)
            self.status.set_text(_("Resolving IP ..."))
            gtk.gdk.window_process_all_updates()
            if not ip:
                try:
                    ip = gethostbyname(hostname)
                except socketerror:
                    push_notification(_("Cannot resolve Hostname %s\n") % hostname,level=2)
                    self.window.destroy()
                    return True
            #### hostname isn't needed in the following code
            #### -> avoid function failure due to a failed reverse DNS lookup
            # if not hostname:
            #     try:
            #         hostname = gethostbyaddr(ip)[0]
            #     except hosterror:
            #         print_debug("Cannot reverse resolve IP %s" % ip)
            #         self.window.destroy()
            #         return True
            push_notification(_("Hostname » %(hostname)s, IP » %(ip)s\n") % { "hostname": hostname, "ip": ip })
            # Step 2: Retrieve workgroup from IP (and add to database)
            self.status.set_fraction(0.4)
            self.status.set_text(_("Resolving Workgroup..."))
            gtk.gdk.window_process_all_updates()
            query_workgroup(ip, True)
            # Step 3: Retrieve SMB hostname from IP (and add to datebase)
            self.status.set_fraction(0.6)
            self.status.set_text(_("Resolving NetBIOS Hostname..."))
            gtk.gdk.window_process_all_updates()
            query_host(ip, True)
            # Step 4: Scan for all shares on the host (and add to datebase)
            self.status.set_fraction(0.8)
            self.status.set_text(_("Scanning for all Shares..."))
            gtk.gdk.window_process_all_updates()
            scan_shares(ip, True)
            # Step 5: Add share manually to datebase if not found in Step 4
            self.status.set_fraction(1.0)
            if not hostonly:
                self.status.set_text(_("Appending user defined Share..."))
                gtk.gdk.window_process_all_updates()
                cursor = db.cursor()
                hostid = cursor.execute("""SELECT id FROM hosts WHERE ip = ?""", ( ip, )).fetchone()[0]
                result = cursor.execute("""SELECT * FROM shares WHERE name = ? AND host = ?""", (url.group(2),hostid)).fetchall()
                if len(result) == 0:
                    comment = u"Added manually..."
                    dblock.acquire()
                    cursor.execute("""INSERT INTO shares (name,host,comment,manual) VALUES (?,?,?,?);""", (url.group(2),hostid,comment,1))
                    dblock.release()
            self.window.destroy()
            return True
