#!/usr/bin/env python

import socket
import threading
import time

import tftpy
import netifaces

from transmitter import RF

DEBUG = False

class SocketInterferer(object):
    """
    Socket-based interferer.

    Opens a listening socket and waits for incoming requests and commands.

    """
    
    def __init__(self):
        self.listen_port = 42000

        self.radio_command = 'off'
        self.radio_transmitter = Radio()



    def setup_socket(self):
        """
        Setup incoming socket.

        """
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        try:
            self.sock.bind(('',self.listen_port))
        except socket.error:
            time.sleep(0.5)
            self.sock.bind(('',self.listen_port))

        self.sock.listen(5)
        self.min_delay = 0.001  # seconds
        if DEBUG:
            print 'Listen on port: ', self.listen_port


    def open_socket(self):
        """
        Open socket and listen for data.

        """
        newsock, client_addr = self.sock.accept()
        data = newsock.recv(1024)
        data = data.split(',')
        # if DEBUG:
        #     print newsock.getpeername()
        newsock.close()
        if DEBUG:
            print '\ndata: ', data
        return data



    def control_radio(self, data):
        freq = int(data[0])
        command = data[1]

        if command == 'off':
            self.radio_transmitter.set_radio_state('off')
            
        else:
            self.radio_transmitter.set_freq(freq)
            self.radio_transmitter.set_radio_state('on')


    def run(self):
        """
        Run the socket-based interferer.

        """
        self.radio_transmitter.start()

        while True:
            self.setup_socket()
            data = self.open_socket()
            self.control_radio(data)
            # time.sleep(0.1)


    def stop(self):
        
        self.radio_transmitter.join()




























        

class Radio(threading.Thread):
    """
    Threaded radio interferer.

    """

    def __init__(self):
        threading.Thread.__init__(self)
        self.stop_event = threading.Event()
        self.radio_current_state = 'off'
        self.radio_last_state = 'off'
        self.rf = RF()


    def set_radio_state(self, state):
        """
        Control radio operation.

        This function provides a method of controlling operation of the
        radio.

        Parameters
        ----------
        state : str
            One of {`on` | `off` }

        """
        # if state == 'on':
        #     self.current_radio_state = 'on'
        
        # self.radio_last_state = self.radio_current_state
        self.radio_current_state = state


    def set_freq(self, freq):
        """
        Set radio frequency.

        """
        self.freq = freq


    def join(self, timeout=None):
        """
        Stop radio subsystem.

        """
        self.stop_event.set()
        self.rf.close_gpio()
        threading.Thread.join(self, timeout)

        

    def run(self):
        """
        Run radio interferer.

        """
        print "Interferer OFF"

        while not self.stop_event.isSet():
            if self.radio_current_state == 'on':
                if self.radio_last_state == 'on':
                    try:
                        self.rf.run(self.freq)
                    except Exception as e:
                        print e
                        time.sleep(0.001)
                    self.radio_last_state = 'on'
                elif self.radio_last_state == 'off':
                    print "Interferer ON"
                    try:
                        self.rf.run(self.freq)
                    except Exception as e:
                        print e
                        time.sleep(0.001)
                    self.radio_last_state = 'on'
                else:
                    print "Interferer error:"
                    print "self.radio_current_state == `on`"
                    print "self.radio_current_state == ???"

            elif self.radio_current_state == 'off':
                if self.radio_last_state == 'on':
                    print "Interferer OFF"
                    self.radio_last_state = 'off'
                    continue
                elif self.radio_last_state == 'off':
                    self.radio_last_state = 'off'
                    continue
                else:
                    print "Interferer error:"
                    print "self.radio_current_state == `off`"
                    print "self.radio_current_state == ???"
                    
            else:
                print "Interferer error:"
                print "self.radio_current_state == `???`"


            
        


if __name__=='__main__':
    main = SocketInterferer()
    try:
        main.run()
    except KeyboardInterrupt:
        main.stop()







            # if self.radio_current_state == 'on':
            #     if self.radio_last_state == 'on':
            #         try:
            #             self.rf.run(self.freq)
            #         except Exception as e:
            #             print e
            #             time.sleep(0.001)
            #         self.radio_last_state = 'on'
            #     elif self.radio_last_state == 'off':
            #         print "Interferer ON"
            #         try:
            #             self.rf.run(self.freq)
            #         except Exception as e:
            #             print e
            #             time.sleep(0.001)
            #         self.radio_last_state = 'on'
            #     else:
            #         print "Interferer error:"
            #         print "self.radio_current_state == `on`"
            #         print "self.radio_current_state == ???"

            # elif self.radio_current_state == 'off':
            #     if self.radio_last_state == 'on':
            #         print "Interferer OFF"
            #         self.radio_last_state = 'off'
            #         continue
            #     elif self.radio_last_state == 'off':
            #         self.radio_last_state = 'off'
            #         continue
            #     else:
            #         print "Interferer error:"
            #         print "self.radio_current_state == `off`"
            #         print "self.radio_current_state == ???"
                    
            # else:
            #     print "Interferer error:"
            #     print "self.radio_current_state == `???`"



# class Interferer(object):

#     def __init__(self):
#         self.remote_file = 'command_file'
#         self.local_file = 'local_file'

#         tftp_server = '192.168.42.10'
#         tftp_port = 69
#         self.client = tftpy.TftpClient(tftp_server, tftp_port)

#         self.ip = netifaces.ifaddresses('eth0')[netifaces.AF_INET][0]['addr']

#         self.radio_command = 'off'

#         self.radio_transmitter = Radio()
        

    



#     def tftp_get(self):
#         try:
#             self.client.download(self.remote_file, self.local_file)
#         except TypeError as e:
#             print e
#             print "\nCaught error, trying to recover"
#             time.sleep(1)
#             self.client.download(self.remote_file, self.local_file)


#     def check_file(self):
#         f = open(self.local_file, 'rt')
#         self.lines = f.readlines()
#         f.close()
#         if self.lines[-1] != 'fin\n':
#             return False
#         else:
#             return True


#     def parse_file(self):
#         if self.ip == '192.168.42.61':
#             line = self.lines[0]
#         elif self.ip == '192.168.42.62':
#             line = self.lines[1]
#         elif self.ip == '192.168.42.63':
#             line = self.lines[2]
#             pass
#         elif self.ip == '192.168.42.64':
#             line = self.lines[3]
#         else:
#             print "File parsing error"
        
#         line = line.strip('\n')
#         if line == '---------':
#             self.radio_command = 'off'
#         else:
#             self.radio_command = 'on'
#             self.radio_freq = int(line)



#     def run(self):
#         self.radio_transmitter.start()

#         while True:
#             self.tftp_get()
#             if self.check_file():
#                 # print "Received complete file."
#                 self.parse_file()
#                 if self.radio_command == 'off':
#                     # print "Turning radio off"
#                     self.radio_transmitter.set_radio_state('off')

#                 else:
#                     # print "Turning radio on"
#                     self.radio_transmitter.set_freq(self.radio_freq)
#                     self.radio_transmitter.set_radio_state('on')

#                 time.sleep(0.1)

#             else:
#                 print "Did not receive complete file!"
#                 time.sleep(0.1)
            


#     def stop(self):
#         self.radio_transmitter.join()

