#!/usr/bin/env python
'''
Copyright (C) 2012, Digium, Inc.
Kinsey Moore <kmoore@digium.com>

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

import sys
import logging

from twisted.internet import reactor

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

LOGGER = logging.getLogger(__name__)

class GenericCCSSTest(TestCase):
    event_count = 0
    success_count = 0

    def __init__(self):
        TestCase.__init__(self)
        self.reactor_timeout = 50
        self.create_asterisk(2)

    def handle_failure(self, reason):
        LOGGER.warn("error sending originate:")
        LOGGER.warn(reason.getTraceback())
        self.stop_reactor()

        return reason

    def ami_connect(self, ami):
        if ami.id == 0:
            self.ami[0].registerEvent('UserEvent', self.ccss_callback)
        else:
            LOGGER.info("Initiating the blocking call from dialplan to bob")
            df = self.ami[1].originate("sip/bob", "dpwait", "1234", 1)
            df.addErrback(self.handle_failure)
            self.ami[1].registerEvent('UserEvent', self.ccss_callback)

    def ccss_callback(self, ami, event):
        if event['userevent'] != 'CCSSStatus':
            return

        self.event_count += 1

        if event['status'] == "sub":
            LOGGER.info("subroutine executed as expected")
            self.success_count += 1
        elif event ['status'] == "macro":
            LOGGER.info("macro executed as expected")
            self.success_count += 1
        elif event ['status'] == "callback":
            LOGGER.info("callback executed as expected")
            self.success_count += 1
        elif event ['status'] == "BOB":
            LOGGER.info("Bouncing a call off the ccss test instance (ast2) now that bob is occupied")
            df = self.ami[0].originate("local/1234@dial-alice", "dpwait", "1234", 1)
            df.addErrback(self.handle_failure)
        elif event ['status'] == "call-failed":
            # since we now have a failed call, run the call completion request
            LOGGER.info("Requesting CCBS")
            df = self.ami[0].originate("local/1235@dial-alice", "dpwait", "1234", 1)
            df.addErrback(self.handle_failure)
        elif event ['status'] == "ccbs-requested":
            # CCBS requested, request channel list
            LOGGER.info("CCBS requested, getting channel list")
            df = self.ami[0].status().addCallbacks(self.status_callback, self.status_failed)

        self.are_we_there_yet()

    def are_we_there_yet(self):
        if self.event_count == 6:
            if self.success_count == 3:
                self.passed = True
            self.stop_reactor()

    def status_callback(self, result):
        # hangup all channels listed on the second instance
        for status_result in result:
            if 'context' in status_result and\
                status_result['context'] == 'bob-incoming':
                self.ami[0].hangup(status_result['channel'])

    def status_failed(self, reason):
        pass

    def run(self):
        TestCase.run(self)
        self.create_ami_factory(2)


def main():
    test = GenericCCSSTest()
    test.start_asterisk()
    reactor.run()
    test.stop_asterisk()

    if not test.passed:
        return 1

    return 0

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

