#!/usr/bin/env python
'''
Copyright (C) 2010, Digium, Inc.
Erin Spiceland <espiceland@digium.com>

This program is free software, distributed under the terms of
the GNU General Public License Version 2.
'''

import sys
import os
from twisted.internet import reactor
from starpy import fastagi

sys.path.append("lib/python")
from asterisk.asterisk import Asterisk

workingdir = "fastagi/sounds"
testdir = "tests/fastagi"


class FastAGIRecordFileTest:
    def __init__(self):
        self.passed = {
            "DTMF": False,
            "HANGUP": False
        }
        self.test = "DTMF"
        self.timeout = 30
        self.key = "fastagitest"
        self.overall_result = True
        self.agi = ""

        # Listen for results from dialplan
        self.agi_factory = fastagi.FastAGIFactory(self.do_test)
        reactor.listenTCP(4573, self.agi_factory, self.timeout, '127.0.0.1')
        reactor.callWhenRunning(self.run)

        self.ast1 = Asterisk(base=workingdir)
        self.ast1.install_configs("%s/configs/ast1" % (testdir))
	self.audio_file = "%s/talking.ulaw" % (workingdir)

    def on_record_failure(self, reason):
        if os.path.exists(self.audio_file):
            print "file exists"

        print "file size is", os.path.getsize(self.audio_file)
        self.passed[self.test] = False
        print 'Could not record file:', reason.getTraceback()
        if self.test is "DTMF":
            self.test = "HANGUP"
            reactor.callLater(0, self.launch_test())
        else:
            self.result_changed()

    def on_record_success(self, result):
        try:
            digit = chr(int(result[0]))
        except:
            digit = None

        print "Recording terminated by %s (%s) after %s bytes." \
            % (result[1], digit, result[2])
        if os.path.exists(self.audio_file):
            file_size = os.path.getsize(self.audio_file)
            if file_size == 0:
                print "The file was created, but it is empty."
                self.passed[self.test] = False
            elif result[2] == file_size:
                print "Data was recorded, and data length matches what was", \
                    "reported during the %s test." % self.test
                self.passed[self.test] = True
            else:
                print "Some data was recorded, but the data length does not", \
                    "match what was reported during the %s test." % self.test
                self.passed[self.test] = False
        else:
            print "The file doesn't exist."
            self.passed[self.test] = False

        if self.test is "DTMF":
            self.test = "HANGUP"
            reactor.callLater(0, self.launch_test)
        else:
            self.result_changed()

    # This gets invoked by the dialplan when the call is answered
    def do_test(self, agi):
        self.agi = agi
        return agi.recordFile("%s/talking" % (workingdir), "ulaw", "#", "3"
            ).addCallback(self.on_record_success).addErrback(self.on_record_failure)

    def read_result(self):
        self.agi.finish()
        self.stop_reactor()
        for t, r in self.passed.iteritems():
            if self.passed[t] is False:
                self.overall_result = False

	if self.overall_result is True:
            print "Success"
	else:
            print "Failed"

    def stop_reactor(self):
        def __finish_stop(result):
            print "Stopping Reactor ..."
            if reactor.running:
                reactor.stop()
            return result

        df = self.ast1.stop()
        df.addCallback(__finish_stop)

    def launch_test(self):
        print "Originating call to begin test which terminates recording",\
            "with", self.test
        if self.test is "DTMF":
            self.ast1.cli_originate("Local/508@agitest extension 1@record-file")
        elif self.test is "HANGUP":
            self.ast1.cli_originate("Local/509@agitest extension 2@record-file")
        else:
            self.result_changed()

    # Read result before timeout
    def result_changed(self):
        if self.passed['DTMF'] is True and self.passed['HANGUP'] is True:
            self.read_result()

    def run(self):
        def __finish_start_ops(result):
            self.launch_test()
            reactor.callLater(self.timeout, self.stop_reactor)
            return result

        print "Starting Asterisk"
        df = self.ast1.start()
        df.addCallback(__finish_start_ops)


def main():
    test = FastAGIRecordFileTest()
    reactor.run()
    if test.overall_result is not True:
        return 1

    return 0

if __name__ == "__main__":
    sys.exit(main() or 0)
