#!/usr/bin/python
import sys
import os
import subprocess
import time

macs = {'sample':'00:00:00:00:00:00'}

def wake(host, tries=5, sleep=30, debug=False):
    stdout = None
    if not debug:
        stdout = file('/dev/null', 'w')

    these = [macs[host]]
    try:
        these.append(macs[host + '-wifi'])
    except KeyError:
        pass

    for x in xrange(tries):
        if not subprocess.call(['/bin/ping', '-W', '5', '-c', '2', host],
                               stdout=stdout):
            print '%s is awake' % host
            if not debug:
                stdout.close()
            return True

        print 'waking %s' % host
        for mac in these:
            subprocess.call(['/bin/sudo', '/sbin/ether-wake', '-i', 'em1', mac],
                            stdout=stdout)
        time.sleep(sleep)

    if not debug:
        stdout.close()
    print 'couldn\'t wake %s' % host
    return False

def user():
    import pwd
    return pwd.getpwuid(os.getuid()).pw_name

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser(
        description='send WoL (Wake-on-LAN) packets')

    parser.add_argument('host', type=str, help='hostname to wake up',
                        choices=macs.keys())
    parser.add_argument('--daemon', choices=['start','stop'], default=None,
                        help='start or stop in daemon (background) mode')
    parser.add_argument('-w', '--wait', type=int, default=30,
                        help='seconds to wait after one try of WoL packet for system to '
                        'wake up')
    parser.add_argument('-t', '--tries', type=int, default=5,
                        help='number of times to attempt a WoL packet')
    parser.add_argument('-d', '--debug', action='store_true',
                        help='run with no output suppression for debugging')
    parser.add_argument('-i', '--interval', type=int, default=9,
                        help='in daemon mode, how long to periodically re-run WoL')
    args = parser.parse_args()

    # if we aren't stopping a daemon, do a wake() right away
    if args.daemon != 'stop' and not wake(args.host, tries=args.tries, sleep=args.wait, debug=args.debug):
        sys.exit(1)

    # if we aren't in daemon mode, we're done
    if args.daemon:
        import daemon
        class WakeDaemon(daemon.Daemon):
            def run(self):
                while(True):
                    time.sleep(60 * args.interval)
                    wake(args.host, tries=args.tries, sleep=args.wait, debug=args.debug)
        stdout='/dev/null'
        if args.debug:
            stdout = '/dev/stdout'
        
        pidfile = '/tmp/wake_up.%s.%s.pid' % (user(), args.host)

        if args.debug:
            print args.daemon, pidfile

        waker = WakeDaemon(pidfile, stdout=stdout)

        if args.daemon == 'start':
            waker.start()
        else:
            waker.stop()

