'''Module containing variety of system-jamming functions,
including CPU, RAM, and TCP-based functions'''
from subprocess import Popen
from multiprocessing import Process
import socket
from time import sleep
from time import time as get_time
import os


def jam_cpu(time, pnum):
    '''Jam CPU by using all available cycles to discard empty data'''
    jam_cpu_command = ['yes']
    devnull = open(os.devnull, 'r')
    print "Process " + str(pnum) + " initialized: CPU"
    new_jprocess = Popen(jam_cpu_command, stdout=devnull, stderr=devnull)
    sleep(time)
    print "Killing process " + str(pnum) + " with PIDs " + str(new_jprocess.pid) + "."
    os.kill(new_jprocess.pid, 9)


def jam_tcp(time, pnum):
    '''Jam CPU by overloading network stack with TCP packets'''
    jam_tcp_message = bytes('Jam.', 'UTF-8')
    print "Process " + str(pnum) + " initialized: TCP"
    stop_time = get_time() + time
    jam_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    jam_socket.connect(('1.2.3.4', 666))
    while get_time() < stop_time:
        jam_socket.send(jam_tcp_message)
    print "Process " + str(pnum) + " finished."


def jam_mem(pnum):
    '''Jam memory by running fork-bomb'''
    jam_mem_command = [':(){ :|: & };:']
    print "Process " + str(pnum) + " initialized: NUKE"
    Popen(jam_mem_command, shell=True, executable='/bin/bash')

JFUNCTIONS = {'cpu': jam_cpu, 'ram': jam_mem, 'tcp': jam_tcp}


def start_process(jtype, time, pnum):
    '''Start the jamming process'''
    new_jprocess_target = JFUNCTIONS[jtype]
    new_jprocess = Process(target=new_jprocess_target, args=(time, pnum))
    new_jprocess.start()


def nuke_system(intensity, countdown):
    '''Jam the entire system, a system-nuke of sorts'''
    for i in range(countdown):
        print str(countdown - i) + '...'
        sleep(1)
    print "NUKE!"
    for i in range(intensity):
        JFUNCTIONS['ram'](i + 1)