#!/usr/bin/python

import os
import re
import sys

import commands
import logging
import socket
import struct
import gettext

from gettext import gettext as _

from optparse import OptionParser

class Route(object):
    """Gets routing information from the system.
    """

    # auxiliary functions
    def _hex_to_dec(self, string):
        """Returns the integer value of a hexadecimal string s
        """
        return int(string, 16)

    def _num_to_dotted_quad(self, number):
        """Convert long int to dotted quad string
        """
        return socket.inet_ntoa(struct.pack("<L", number))

    def _get_default_gateway_from_proc(self):
        """"Returns the current default gateway, reading that from /proc
        """
        logging.debug("Reading default gateway information from /proc")
        try:
            file = open("/proc/net/route")
            route = file.read()
        except:
            logging.error("Failed to read def gateway from /proc")
            return None
        else:
            h = re.compile("\n(?P<interface>\w+)\s+00000000\s+(?P<def_gateway>[\w]+)\s+")
            w = h.search(route)
            if w:
                if w.group("def_gateway"):
                    return self._num_to_dotted_quad(self._hex_to_dec(w.group("def_gateway")))
                else:
                    logging.error("Could not find def gateway info in /proc")
                    return None
            else:
                logging.error("Could not find def gateway info in /proc")
                return None

    def _get_default_gateway_from_bin_route(self):
        """Get default gateway from /sbin/route -n
        Called by get_default_gateway and is only used if could not get that from /proc
        """
        logging.debug("Reading default gateway information from route binary")
        routebin = commands.getstatusoutput("export LANGUAGE=C; /usr/bin/env route -n")

        if routebin[0] == 0:
            h = re.compile("\n0.0.0.0\s+(?P<def_gateway>[\w.]+)\s+")
            w = h.search(routebin[1])
            if w:
                def_gateway = w.group("def_gateway")
                if def_gateway:
                    return def_gateway

        logging.error("Could not find default gateway by running route")
        return None

    def get_hostname(self):
        return socket.gethostname()

    def get_default_gateway(self):
        t1 = self._get_default_gateway_from_proc()
        if not t1:
            t1 = self._get_default_gateway_from_bin_route()

        return t1

def ping(host, interface, count, deadline, verbose=False):
    command = "ping -c %s -w %s %s" % (count, deadline, host)
    if interface:
        command = "ping -I%s -c %s -w %s %s" % (interface, count, deadline, host)

    reg = re.compile(r"(\d) received")
    packets_received = 0

    output = os.popen(command)
    for line in output.readlines():
        if verbose:
            print line.rstrip()

        received = re.findall(reg, line)
        if received:
            packets_received = int(received[0])

    return packets_received

def main(args):

    gettext.textdomain("checkbox")

    default_count = 2
    default_delay = 4

    usage = "%prog [HOST]"
    parser = OptionParser(usage=usage)
    parser.add_option("-c", "--count",
        default=default_count,
        type="int",
        help="Number of packets to send.")
    parser.add_option("-d", "--deadline",
        default=default_delay,
        type="int",
        help="Timeouts in seconds.")
    parser.add_option("-v", "--verbose",
        default=False,
        action="store_true",
        help="Be verbose.")
    parser.add_option("-I", "--interface",
        help="Interface to ping from.")
    (options, args) = parser.parse_args(args)

    if args:
        host = args.pop(0)
    else:
        route = Route()
        host = route.get_default_gateway()

    received_packets = 0
    if host:
        received_packets = ping(host, options.interface, options.count, options.deadline,
                                options.verbose)

    if received_packets == 0:
        print _("No Internet connection")
        return 1
    elif received_packets != options.count:
        print _("Connection established lost a packet")
        return 1
    else:
        print _("Internet connection fully established")
        return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
