#!/usr/bin/python3

# Copyright (C) 2006-2015 Avencall
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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, see <http://www.gnu.org/licenses/>

import os
import sys

import xivo_dao
from xivo_auth_client import Client as Auth
from xivo_confd_client import Client as Confd
from xivo_dao import accesswebservice_dao
from xivo_dao import asterisk_conf_dao

XIVO_AUTH_TOKEN_TIMEOUT = 10

XIVO_CONFD_CONFIG = {
    'host': 'localhost',
    'port': 9487,
    'https': 'False',
    'verify_certificate': 'False'
}

MDS_CONFD_CONFIG = {
    'host': 'xivo',
    'port': 9486,
    'https': 'True',
    'verify_certificate': 'False',
    'username': 'mdsws'
}


def mds_get_confd_password(user_name):
    return accesswebservice_dao.get_password(user_name)


def mds_get_confd_host():
    xivo_dao.init_db_from_config()
    mediaservers = asterisk_conf_dao.find_all_mediaservers()
    for mds in mediaservers:
        if mds.name == 'default':
            return mds.voip_ip


def get_confd_client_config():
    is_mds = os.path.exists('/var/lib/xivo/mds_enabled')

    if is_mds:
        default_confd_config = MDS_CONFD_CONFIG
        default_confd_config['host'] = mds_get_confd_host()
    else:
        default_confd_config = XIVO_CONFD_CONFIG

    config = {
        'host': os.environ.get('CONFD_HOST', default_confd_config['host']),
        'port': int(os.environ.get('CONFD_PORT', default_confd_config['port'])),
        'https': os.environ.get('CONFD_HTTPS', default_confd_config['https']).lower() == 'true',
        'verify_certificate': os.environ.get(
            'CONFD_VERIFY_CERT', default_confd_config['verify_certificate']).lower() == 'true'
    }

    username = os.environ.get('CONFD_USERNAME', default_confd_config.get('username'))
    if username:
        config['username'] = username
        passwd = os.environ.get('CONFD_PASSWORD', mds_get_confd_password(username) if is_mds else None)
        if passwd:
            config['password'] = passwd

    if is_mds:
        auth = Auth(config['host'], username=config['username'], password=config['password'],
                    verify_certificate=config['verify_certificate'])
        token_data = auth.token.new('xivo_service', expiration=XIVO_AUTH_TOKEN_TIMEOUT)
        config['token'] = token_data['token']

    return config


def get_voicemail(client, number, context):
    response = client.voicemails.list(search=number)

    found = [v for v in response['items']
             if v['number'] == number and v['context'] == context]

    assert len(found) > 0, "voicemail {}@{} not found!".format(number, context)
    assert len(found) == 1, "more than one voicemail found when searching for {}@{}".format(number, context)
    return found[0]


def update_password(client, voicemail, new_password):
    voicemail['password'] = new_password
    client.voicemails.update(voicemail)


if __name__ == "__main__":
    if len(sys.argv) != 4:
        raise ValueError("Missing args!")

    context = sys.argv[1]
    number = sys.argv[2]
    new_password = sys.argv[3]

    confd_client_config = get_confd_client_config()
    client = Confd(**confd_client_config)

    voicemail = get_voicemail(client, number, context)
    update_password(client, voicemail, new_password)
