#!/usr/bin/env python
'''
Copyright (C) 2010, Digium, Inc.
Terry Wilson <twilson@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
import pjsua as pj
import threading

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

workingdir = "sip/refer_replaces_to_self"
testdir = "tests/%s" % workingdir

def log_cb(level, str, len=len(str(str))):
    print str,

class TestAccountCallback(pj.AccountCallback):

    def __init__(self, account):
        self.sem = threading.Semaphore(0)
        pj.AccountCallback.__init__(self, account)

    def wait(self):
        if self.sem:
            self.sem.acquire()

    def on_reg_state(self):
        if self.sem:
            if self.account.info().reg_status >= 200:
                self.sem.release()
                self.sem = None

    def on_incoming_call(self, call):
        call.set_callback(TestCallCallback(call))
        call.answer(200)


class TestCallCallback(pj.CallCallback):
    def __init__(self, call=None):
        pj.CallCallback.__init__(self, call)

    def on_state(self):
        if self.call.info().state == pj.CallState.CONFIRMED:
            self.call.transfer_to_call(self.call)

    def on_transfer_status(self, code, reason, final, cont):
        if final:
            global call_sem

            if code == 404:
                global passed
                passed = True 

            if call_sem:
                call_sem.release()
 

class ReplaceSelfTest:
    def __init__(self):
        reactor.callWhenRunning(self.run)

        print "Creating Asterisk instance ..."

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

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

    def start_asterisk(self):
        print "Starting Asterisk instance ..."
        self.ast1.start()

    def stop_asterisk(self):
        print "Stopping Asterisk instance ..."
        self.ast1.stop()

    def run(self):
        self.start_asterisk()

        # We shouldn't take longer than 20 seconds to perform this test
        reactor.callLater(20, self.stop_reactor)

        lib = pj.Lib()

        global call_sem
        global passed
        call_sem = threading.Semaphore(0)
        passed = False

        try:
            #lib.init(log_cfg = pj.LogConfig(level=4, callback=log_cb))
            lib.init()
            lib.create_transport(pj.TransportType.UDP, pj.TransportConfig())
            lib.set_null_snd_dev()
            lib.start()

            ext_a = lib.create_account(pj.AccountConfig("127.0.0.1", "6001", "1234"))
            ext_b = lib.create_account(pj.AccountConfig("127.0.0.1", "6002", "1234"))
            ext_a_cb = TestAccountCallback(ext_a)
            ext_b_cb = TestAccountCallback(ext_b)
            ext_a.set_callback(ext_a_cb)
            ext_b.set_callback(ext_b_cb)
            ext_a_cb.wait()
            ext_b_cb.wait()

            call = ext_a.make_call("sip:6002@127.0.0.1")

            call.transfer_to_call(call)
            call_sem.acquire()

            del call

            lib.destroy()
            lib = None

            self.stop_reactor()

        except pj.Error, e:
            print "Exception: " + str(e)
            self.stop_reactor()

def main():
    test = ReplaceSelfTest()
    reactor.run()
    test.stop_asterisk()

    global passed
    if passed:
        print "PASSED"
        return 0

    print "FAILED"
    return 1


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


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