#!/usr/bin/env python
'''
Copyright (C) 2010, Digium, Inc.
Matthias Nick <mnick86@gmail.com>

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

import sys
import os
import math
from twisted.application import service, internet
from twisted.internet import reactor
from starpy import fastagi

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

workingdir = "blind-transfer-parkingtimeout"
testdir = "tests/%s" % workingdir

class BlindTransferTest:
    def __init__(self):
        self.passed = False
        self.done = False

        # Test timeout in seconds
        self.timeout = 60
        self.last_step = ""

        # FastAGI, listen for results from dialplan
        self.agi_b = fastagi.FastAGIFactory(self.get_result_b)
        reactor.listenTCP(4574, self.agi_b, self.timeout, '127.0.0.1')

        reactor.callWhenRunning(self.run)

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

        self.ast2 = Asterisk(base=workingdir)
        self.ast2.install_configs("%s/configs/ast2" % (testdir))

   # This gets invoked by the dialplan when test succeeds.
    def get_result_b(self, agi):
        self.log_last_step("got AGI connection from userB -> test successful")
        self.passed = True
        reactor.callLater(2, self.read_result)
        return agi.finish()

    def read_result(self):
        if self.done:
            return
        self.done = True
        self.log_last_step("Reading results")

        # get lock output in case of deadlock before tearing down.
        self.ast1.cli_exec("core show locks")
        self.ast2.cli_exec("core show locks")

        # if channels are still up for some reason, we want to know that
        self.ast1.cli_exec("core show channels")
        self.ast2.cli_exec("core show channels")

        if (self.passed):
            self.log_last_step("Test Passed...")
        else:
            self.log_last_step("Test Failed... view result of "
             "'core show globals' in log for more detailed failure results.")

        if reactor.running:
            print "Stopping Reactor ..."
            reactor.stop()

    # This is a blind transfer test with parkingtimeout.
    # 1.  A calls B
    # 2.  B dials # -> 700, to park A.
    # 3.  A gets parkingtimeout and returns to B
    # 4.  B reports results to FastAGI and hangup
    def launch_test(self):
        self.log_last_step("Originating call to begin test")
        self.ast1.cli_originate(
         "IAX2/userA@127.0.0.1:4571/b_exten extension a_dials@parking")

    def start_asterisk(self):
        self.log_last_step("Starting Asterisk")
        self.ast1.start()
        self.ast2.start()

    def stop_asterisk(self):
        self.ast1.stop()
        self.ast2.stop()

    def log_last_step(self, step):
        print step
        self.last_step = step

    def run(self):
        self.start_asterisk()

        # start test in 5 seconds
        reactor.callLater(5, self.launch_test)

        # stop and read results after timeout
        reactor.callLater(self.timeout, self.read_result)


def main():
    # Run Blind Transfer Test
    blind_transfer_test = BlindTransferTest()
    reactor.run()
    blind_transfer_test.stop_asterisk()
    if blind_transfer_test.passed != True:
        return 1
    return 0

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

# vim:sw=4:ts=4:expandtab:textwidth=79
