class QaEnergyDetector(gr_unittest.TestCase):
    """
    QA related to EnergyDetector class.
    """

    def setUp(self):
        """
        Set globals for all tests. Called before a test is started.
        """
        self.tb = OpERAFlow(name='top')

    def tear_down(self):
        """
        Destroy globals for all tests. Called right after a test if finished.
        """
        self.tb = None

    def test_001(self):
        """
        Test the energy of a simple sequence (1, 2, -1, -2).
        """
        # input and expected results
        src_data = (1, 1, 1, 1)
        expected_result = 1

        # blocks
        fft_size = len(src_data)
        mavg_size = 1

        src = blocks.vector_source_c(data=src_data)
        dst = blocks.probe_signal_f()
        ed = EnergySSArch(fft_size, mavg_size, EnergyDecision(1))
        #radio_device = RadioDevice(the_source = src, the_sink = dst)

        radio_device = RadioDevice()
        radio_device.add_arch(source=src, arch=ed, sink=dst, uhd_device=None, name='ed')
        ################ FIM NOVO RADIO DEVICE

        ## flowgraph
        ##self.tb.add_arch(ed, radio_device, 'ed')
        self.tb.add_radio(radio_device)
        self.tb.run()

        result_data = dst.level()
        self.assertEqual(expected_result, result_data)

    def test_002(self):
        """
        Test a sequence with float number (0.1, 0.1, 0.1, 0.1).
        """
        # input and expected results
        src_data = (0.1, 0.1, 0.1, 0.1)
        expected_result = 0

        # blocks
        fft_size = len(src_data)
        mavg_size = 1

        src = blocks.vector_source_c(data=src_data)
        ed = EnergyDetectorC(fft_size, mavg_size, EnergyDecision(1))

        dst = blocks.probe_signal_f()

        # flowgraph
        self.tb.connect(src, ed, dst)
        self.tb.run()

        result_data = dst.level()
        self.assertEqual(expected_result, result_data)

    def test_003(self):
        """
        Test EDTopBlock with the input (1, 1, 1, 1, 1, 1, 1, 1).
        """
        arr = (1, 1, 1, 1, 1, 1, 1, 1)
        expected_out = 8

        ed = EnergySSArch(fft_size=len(arr),
                          mavg_size=8,
                          algorithm=EnergyDecision(expected_out - 1)
                          )

        src = blocks.vector_source_c(data=arr, vlen=1)
        sink = blocks.probe_signal_f()

        device = RadioDevice()
        device.add_arch(source=src, arch=ed, sink=sink, uhd_device=None, name='ed')

        self.tb.add_radio(device, 'ed')
        self.tb.run()

        ##self.assertEqual(1 , device.sink.level()) # didn't work
        self.assertEqual(1, device.output()[0])

    def test_004(self):
        """
        Test EDTopBlock with a simple input (1, 2, 3, 4).
        """
        arr = (1.0, 2.0, 3.0, 4.0)
        expected_result = 30  # before expected result was 2536

        ed = EnergySSArch(fft_size=len(arr),
                          mavg_size=1,
                          algorithm=EnergyDecision(expected_result + 1)  # (expected_out + 1)
                          )

        src = blocks.vector_source_c(data=arr, vlen=1)
        sink = blocks.probe_signal_f()

        device = RadioDevice()
        device.add_arch(source=src, arch=ed, sink=sink, uhd_device=None, name='ed')

        self.tb.add_radio(device, 'ed')

        self.tb.start()
        self.tb.wait()

        ###self.assertEqual(expected_result , device.sink.output()[1])
        self.assertEqual(expected_result, device.ed.output()[1])  # uses 'name' parameter of the add_arch method
class QaFeedback(gr_unittest.TestCase):
    """
    QA tests related to feeback.
    """

    def setUp(self):
        """
        Set globals for all tests. Called before a test is started.
        """
        self.tb = OpERAFlow('QaFeedback')

    def tear_down(self):
        """
        Destroy globals for all tests. Called right after a test if finished.
        """
        self.tb = None


    def test_001(self):
        """
        Test Feedback Algorithm architecture.
        This test validates the feedback architecture when the 'manager' says the channel is idle and the 'learner'
        says is occupied.
        """
        return
        """
	::TODO::
	Update this test.
	"""
        print 't1'
        data_l = [1]
        data_m = [0]

        # Bayes learning parameters
        in_th = 10
        min_th = 0.001
        max_th = 20
        delta_th = 0.001
        k = 1

        # Feeback architecture
        bl_algo = BayesLearningThreshold(in_th=in_th,
                                         min_th=min_th,
                                         max_th=max_th,
                                         delta_th=delta_th,
                                         k=k)
        fb_algo = FeedbackAlgorithm(bl_algo, AlwaysTimeFeedback())

        fb = FeedbackF(fb_algo)

        # Data blocks
        src_l = blocks.vector_source_f(data_l)
        src_m = blocks.vector_source_f(data_m)

        # Flow graph
        tb = gr.top_block()
        tb.connect(src_l, (fb, 0))
        tb.connect(src_m, (fb, 1))

        tb.run()

        # bayes feedback has to be 0  
        self.assertEqual(bl_algo.feedback, 0)

    def test_002(self):
        """
        Test Feedback Algorithm architecture
        This test validates the feedback architecture when the 'manager' says the channel is occupied and the 'learner'
        says is idle.

        """
        return
        """
	::TODO::
	Update this test.
	"""
        data_l = [0]
        data_m = [1]

        # Bayes learning parameters
        in_th = 10
        min_th = 0.001
        max_th = 20
        delta_th = 0.001
        k = 1

        # Feeback architecture
        bl_algo = BayesLearningThreshold(in_th=in_th,
                                         min_th=min_th,
                                         max_th=max_th,
                                         delta_th=delta_th,
                                         k=k)
        fb_algo = FeedbackSSArch2(bl_algo, AlwaysTimeFeedback())  ### learner, manager, a_feedback_strategy

        fb = FeedbackF(fb_algo)

        # Data blocks
        src_l = blocks.vector_source_f(data_l)
        src_m = blocks.vector_source_f(data_m)

        # Flow graph
        tb = gr.top_block()
        tb.connect(src_l, (fb, 0))
        tb.connect(src_m, (fb, 1))

        tb.run()

        # bayes feedback has to be 0  
        self.assertEqual(bl_algo.feedback, 1)


    def test_003(self):
        """
        Test a more elaborate scenario with feedback.
        In this test the FeedbackTopBlock is utilized with n waveform algorithm as manager, an energy and a feedback
        algorithm.
        """
        return
        """
	::TODO::
	Update this test.
	"""

        # Random 'signal' utilized in the test
        arr = [random.random() for i in xrange(1024)]
        fft_size = 1024

        # Bayes learning parameters
        in_th = 1
        min_th = 0.001
        max_th = 20
        delta_th = 0.001
        k = 1

        # Feeback architecture
        bl_algo = BayesLearningThreshold(in_th=in_th,
                                         min_th=min_th,
                                         max_th=max_th,
                                         delta_th=delta_th,
                                         k=k)

        # detectors utilized
        bl = EnergyDetectorC(fft_size, 1, bl_algo)
        ev = WaveformSSArch(fft_size, WaveformDecision(0.7))


        # top block
        t = FeedbackSSArch(block_manager=ev,
                           block_learner=bl,
                           feedback_algorithm=FeedbackAlgorithm(bl_algo, AlwaysTimeFeedback())
                           ### learner, manager, a_feedback_strategy
        )

        source = blocks.vector_source_c(data=arr, vlen=1)
        sink = blocks.probe_signal_f()

        device = RadioDevice()
        device.add_arch(source=source, arch=t, sink=sink, uhd_device=None, name='ss_arch')

        self.tb.add_path(t, device, 'ss')
        self.tb.run()

        # As the waveform will (probably) not detected the channel as occupied, the feedback system should decrease the threshold by 1
        self.assertEqual(0, bl_algo.feedback)