#!/usr/local/bin/python
#
# Copyright (c) 2009 Sippy Software, Inc. All rights reserved.
#
# This file is part of SIPPY, a free RFC3261 SIP stack and B2BUA.
#
# SIPPY is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# For a license to use the SIPPY software under conditions
# other than those described here, or to purchase support for this
# software, please contact Sippy Software, Inc. by e-mail at the
# following addresses: sales@sippysoft.com.
#
# SIPPY is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.

from configparser import RawConfigParser
from .SipConf import SipConf

SUPPORTED_OPTIONS = { \
 'acct_enable':       ('B', 'enable or disable Radius accounting'), \
 'precise_acct':      ('B', 'do Radius accounting with millisecond precision'), \
 'alive_acct_int':    ('I', 'interval for sending alive Radius accounting in ' \
                             'second (0 to disable alive accounting)'), \
 'config':            ('S', 'load configuration from file (path to file)'), \
 'auth_enable':       ('B', 'enable or disable Radius authentication'), \
 'b2bua_socket':      ('S', 'path to the B2BUA command socket or address to listen ' \
                             'for commands in the format "udp:host[:port]"'), \
 'digest_auth':       ('B', 'enable or disable SIP Digest authentication of ' \
                             'incoming INVITE requests'), \
 'foreground':        ('B', 'run in foreground'), \
 'hide_call_id':      ('B', 'do not pass Call-ID header value from ingress call ' \
                             'leg to egress call leg'), \
 'keepalive_ans':     ('I', 'send periodic "keep-alive" re-INVITE requests on ' \
                             'answering (ingress) call leg and disconnect a call ' \
                             'if the re-INVITE fails (period in seconds, 0 to ' \
                             'disable)'), \
 'keepalive_orig':    ('I', 'send periodic "keep-alive" re-INVITE requests on ' \
                             'originating (egress) call leg and disconnect a call ' \
                             'if the re-INVITE fails (period in seconds, 0 to ' \
                             'disable)'), \
 'logfile':           ('S', 'path to the B2BUA log file'), \
 'max_credit_time':   ('I', 'upper limit of session time for all calls in ' \
                             'seconds'), \
 'max_radiusclients': ('I', 'maximum number of Radius Client helper ' \
                             'processes to start'), \
 'pidfile':           ('S', 'path to the B2BUA PID file'), \
 'radiusclient.conf': ('S', 'path to the radiusclient.conf file'), \
 'sip_address':       ('S', 'local SIP address to listen for incoming SIP requests ' \
                             '("*", "0.0.0.0" or "::" to listen on all IPv4 ' \
                             'or IPv6 interfaces)'),
 'sip_port':          ('I', 'local UDP port to listen for incoming SIP requests'), \
 'start_acct_enable': ('B', 'enable start Radius accounting'), \
 'static_route':      ('S', 'static route for all SIP calls'), \
 'static_tr_in':      ('S', 'translation rule (regexp) to apply to all incoming ' \
                             '(ingress) destination numbers'), \
 'static_tr_out':     ('S', 'translation rule (regexp) to apply to all outgoing ' \
                             '(egress) destination numbers'), \
 'allowed_pts':       ('S', 'list of allowed media (RTP) IANA-assigned payload ' \
                             'types that the B2BUA will pass from input to ' \
                             'output, payload types not in this list will be ' \
                             'filtered out (comma separated list)'), \
 'pass_headers':      ('S', 'list of SIP header field names that the B2BUA will ' \
                             'pass from ingress call leg to egress call leg ' \
                             'unmodified (comma-separated list)'), \
 'accept_ips':        ('S', 'IP addresses that we will only be accepting incoming ' \
                             'calls from (comma-separated list). If the parameter ' \
                             'is not specified, we will accept from any IP and ' \
                             'then either try to authenticate if authentication ' \
                             'is enabled, or just let them to pass through'),
 'digest_auth_only':  ('B', 'only use SIP Digest method to authenticate ' \
                             'incoming INVITE requests. If the option is not ' \
                             'specified or set to "off" then B2BUA will try to ' \
                             'do remote IP authentication first and if that fails '
                             'then send a challenge and re-authenticate when ' \
                             'challenge response comes in'), \
 'rtp_proxy_clients': ('S', 'comma-separated list of paths or addresses of the ' \
                             'RTPproxy control socket. Address in the format ' \
                             '"udp:host[:port]" (comma-separated list)')}

class MyConfigParser(RawConfigParser):
    default_section = None
    _private_keys = None

    def __init__(self, default_section = 'general'):
        self.default_section = default_section
        self._private_keys = {}
        RawConfigParser.__init__(self)
        self.add_section(self.default_section)

    def __getitem__(self, key):
        if key.startswith('_'):
            return self._private_keys[key]
        value_type  = SUPPORTED_OPTIONS[key][0]
        if value_type  == 'B':
            return self.getboolean(self.default_section, key)
        elif value_type == 'I':
            return self.getint(self.default_section, key)
        return self.get(self.default_section, key)

    def __setitem__(self, key, value):
        if key.startswith('_'):
            self._private_keys[key] = value
        else:
            self.set(self.default_section, key, str(value))
        return

    def has_key(self, key):
        return self.__contains__(key)

    def __contains__(self, key):
        if key.startswith('_'):
            return key in self._private_keys
        return self.has_option(self.default_section, key)

    def get(self, *args):
        if len(args) == 1:
            return self.__getitem__(args[0])
        return RawConfigParser.get(self, *args)

    def getdefault(self, key, default_value):