#!/usr/bin/env python3

import sys
import getopt
import re
import binascii
import socket

ip_address = "255.255.255.255"
port_number = 9
flag = 0
mac_address = ""
re_ip = r"^(([0-9]|[1-9][0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2([0-4][0-9]|5[0-5]))$"
re_mac = r"^([0-9a-fA-F]{2}\:){5}[0-9a-fA-F]{2}$"

def usage():
    print('''   Usage: Wake on lan
        -h: this information
        -a: address
        -m: mac
        -p: port''')

def isValidIp(_ip):
    if re.match(re_ip, _ip):
        return True
    return False

def isValidMac(_mac):
    if re.match(re_mac, _mac):
        return True
    return False

def isValidPort(_port):
    try:
        int(_port)
        return True
    except ValueError:
        return False
        
def sendMagicPack(_ip, _port, _mac):
    _mac = _mac.replace(':', '')
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
    s.sendto(binascii.unhexlify("ff"*6+_mac*16),(_ip,_port))
    s.close()

try:
    opts, args = getopt.getopt(sys.argv[1:], "ha:m:p:")
    if len(opts) == 0:
        raise getopt.GetoptError("No argument!")
except getopt.GetoptError:
    usage()
    sys.exit(1)

for opt, value in opts:
    if(opt == "-h"):
        usage()
        sys.exit(1)
       
for opt, value in opts: 
    if(opt == "-a"):
        if isValidIp(value):
            print("ip:", value)
            ip_address = value
        else:
            print("Invalid Ip")
            sys.exit(1)
        
for opt, value in opts:
    if(opt == "-p"):
        if isValidPort(value):
            print("port:", value)
            port_number = int(value)
        else:
            print("Invalid port")
            sys.exit(1)
            
for opt, value in opts:
    if(opt == "-m"):
        if isValidMac(value):
            print("mac:", value)
            mac_address = value
            sendMagicPack(ip_address, port_number, mac_address)
            print("A magic pack has been sent.")
        else:
            print("Invalid Mac")
            sys.exit(1)
