#!/usr/bin/env python
'''
Copyright (C) 2011, Digium, Inc.
Jonathan Rose <jrose@digium.com>

This program is free software, distributed under the terms of
the GNU General Public License Version 2.
'''
import fileinput
import sys
import os
import shutil
import logging
from twisted.internet import reactor, defer

sys.path.append("lib/python")
from asterisk.test_case import TestCase
from asterisk.test_suite_utils import file_replace_string
from asterisk.sipp import SIPpScenario
from starpy import manager

logger = logging.getLogger(__name__)

"""
Creates an Asterisk instance with a TLS enabled SIP client and then uses sipp to register that client
with sipp via TLS.
"""
class SIPTLS_Register_Test(TestCase):

    # Preps test objects and configuration additions as well as copies TLS keys to test folder.
    def __init__(self):
        TestCase.__init__(self)

        self.pass_sipp = False
        self.pass_event = False

        # Additional setup for config files and keys
        logger.debug("Building test resources ...")

        self.create_asterisk()

        self.keysdir = self.ast[0].get_path('astkeydir')
        self.etcdir = self.ast[0].get_path('astetcdir')

        # Additional setup for config files and keys
        logger.debug( "Building test resources ...")
        if os.path.exists('%s/configs/ast1/sip_helper.inc' % self.test_name):
            os.remove('%s/configs/ast1/sip_helper.inc' % self.test_name)
        shutil.copy('%s/configs/sip_helper_template.inc' % self.test_name, '%s/configs/ast1/sip_helper.inc' % self.test_name)

        file_replace_string('%s/configs/ast1/sip_helper.inc' % self.test_name, '<<path>>', self.keysdir)

        #recopy sip_helper.inc since it's been changed. Remove first in case one already exists.
        if os.path.exists('%s/sip_helper.inc' % self.etcdir):
            os.remove('%s/sip_helper.inc' % self.etcdir)
        shutil.copy('%s/configs/ast1/sip_helper.inc' % self.test_name, self.etcdir)

        #Now that we've created the Asterisk instances, let's go ahead and remove the sip_helper.inc files

        if os.path.exists('%s/configs/ast1/sip_helper.inc' % self.test_name):
            os.remove('%s/configs/ast1/sip_helper.inc' % self.test_name)

        # initialize test variables
        self.passed = False
        self.tone1 = False
        self.tone2 = False

        if not os.path.exists('%s/' % self.keysdir):
            os.makedirs('%s' % self.keysdir);
        if os.path.exists('%s/keys' % self.keysdir):
            shutil.rmtree('%s/keys' % self.keysdir)
        shutil.copytree('%s/configs/keys' % self.test_name, '%s/keys' % self.keysdir)
        # End of additional setup for config files and keys

    # Sets up callback function for PeerStatus events and runs/evaluates SIPp for the necessary scenario with TLS.
    def ami_connect(self, ami):
        def __stop_test(result):
            if (result.passed):
                self.pass_sipp = True
                self.check_pass_fail()
            return result

        self.ami = ami
        self.ami.registerEvent("PeerStatus", self.check_register_result)
        scenario_def = {
            'scenario': 'register.xml',
            '-p': '5061',
            '-recv_timeout': '1000',
            '-s': 'SIP/v4-in',
            '-t': 'ln',
            '-tls_cert': '%s/configs/keys/serverA.crt' % self.test_name,
            '-tls_key': '%s/configs/keys/serverA.key' % self.test_name,
        }

        scenario = SIPpScenario("tests/channels/SIP/sip_tls_register", scenario_def)
        df = scenario.run(self)
        df.addCallback(__stop_test)

    def check_pass_fail(self):
        if (self.pass_event and self.pass_sipp):
            self.passed = True
            self.stop_reactor()

    # Callback for PeerStatus events, checks to see if the correct peer registered successfully.
    def check_register_result(self, ami, event):
        peer = event.get("peer")
        status = event.get("peerstatus")
        logger.info("PeerStatus event received")

        if peer == "SIP/v4-in":
            logger.info("PeerStatus event peer matched SIP/v4-in")
        else:
            logger.info("PeerStatus event peer did not match SIP/v4-in, was %s" % peer)
            return

        if status == "Registered":
            logger.info("Successful registration for peer %s" % peer)
            self.pass_event = True
            self.check_pass_fail()
            return
        else:
            logger.info("Registration for peer %s in state %s" % (peer, status))
            return

    # Sets up reactor and AMI connection
    def run(self):
        TestCase.run(self)
        self.create_ami_factory()


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

    if test.passed:
        return 0
    return 1

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


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