# -*- coding: utf-8 -*-

# Copyright (C) 2006-2018 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/>

from builtins import str
import time

from xivo_agid import agid
from xivo_agid import objects


MEETME_RECORDINGDIR = '/var/lib/asterisk/sounds/meetme/'

def meetme_authenticate(agi, meetme):

    if not meetme.has_pin():
        return (True, 'USER', None)

    if(agi.get_variable('XUC_CALLSOURCE') == 'MOBILE_APPLICATION'):
        if(meetme.has_admin()):
            return (True, 'ADMIN', meetme.admin_pin)
        return (True, 'USER', meetme.user_pin)
    
    max_len_pin = meetme.max_len_pin()

    retry = 0
    auth = False
    role = None
    pin_entered = None

    agi.appexec('Answer')
    while retry < 3:
        agi.appexec('Read', "PIN,conf-getpin,%s" % max_len_pin)
        pin_entered = agi.get_variable('PIN')

        if pin_entered == meetme.user_pin:
            auth = True
            role = 'USER'
        elif pin_entered == meetme.admin_pin:
            auth = True
            role = 'ADMIN'

        if auth:
            return (auth, role, pin_entered)

        retry += 1
        agi.appexec('Playback', 'conf-invalidpin')

    agi.appexec('Playback', 'vm-goodbye')

    return (auth, role, pin_entered)

def meetme_exceed_max_number(agi, meetme, role):
    if role == 'ADMIN':
        return False

    if not meetme.maxusers or int(meetme.maxusers) < 1:
        return False

    agi.appexec('MeetMeCount', "%s,MEETMECOUNT" % meetme.confno)
    meetmecount = agi.get_variable('MEETMECOUNT')

    if not meetmecount.isdigit():
        return None

    return (int(meetmecount) >= int(meetme.maxusers))

def meetme_set_options(agi, meetme, role):
    options = []

    options.append(meetme.OPTIONS['talkerdetection'])

    if role == 'ADMIN':
        options.append(meetme.OPTIONS['adminmode'])

    if meetme.user_waitingroom and meetme.has_admin():
        if role == 'USER':
            options.append(meetme.OPTIONS['user_waitingroom'])
        elif role == 'ADMIN':
            options.append(meetme.OPTIONS['markedmode'])

    if meetme.musiconhold:
        options.append(''.join([meetme.OPTIONS['musiconhold'],'(',meetme.musiconhold,')']))

    if meetme.user_announcejoinleave == 'yes' and role == 'USER':
        options.append(meetme.OPTIONS['user_announcejoinleave']['yes'])
    elif meetme.user_announcejoinleave == 'noreview' and role == 'USER':
        options.append(meetme.OPTIONS['user_announcejoinleave']['noreview'])

    if meetme.noplaymsgfirstenter:
        options.append(meetme.OPTIONS['noplaymsgfirstenter'])
    if meetme.announceusercount:
        options.append(meetme.OPTIONS['announceusercount'])
    if meetme.quiet:
        options.append(meetme.OPTIONS['quiet'])
    if meetme.record:
        options.append(meetme.OPTIONS['record'])

    return ''.join(options)

def meetme_set_diaplan_vars(agi, meetme, pin, role, options):

    agi.set_variable('MEETME_RECORDINGFILE', MEETME_RECORDINGDIR + "meetme-%s-%s"
                        % (meetme.confno, time.strftime("%Y%m%d-%H%M%S")))

    agi.set_variable('XIVO_REAL_NUMBER', meetme.confno)
    agi.set_variable('XIVO_REAL_CONTEXT', meetme.context)
    agi.set_variable('XIVO_MEETMECONFNO', meetme.confno)
    agi.set_variable('XIVO_MEETMENAME', meetme.name)
    agi.set_variable('XIVO_MEETMENUMBER', meetme.confno)
    agi.set_variable('XIVO_MEETMEPIN', pin)
    agi.set_variable('XIVO_MEETMEOPTIONS', options)
    agi.set_variable('XIVO_MEETMEROLE', role)

    if meetme.preprocess_subroutine:
        preprocess_subroutine = meetme.preprocess_subroutine
    else:
        preprocess_subroutine = ''
    agi.set_variable('XIVO_MEETMEPREPROCESS_SUBROUTINE', preprocess_subroutine)

    if meetme.musiconhold:
        agi.set_variable('CHANNEL(musicclass)', meetme.musiconhold)


def incoming_meetme_set_features(agi, cursor, args):
    xid = agi.get_variable('XIVO_DSTID')

    try:
        meetme = objects.MeetMe(int(xid))
    except (ValueError, LookupError) as e:
        agi.dp_break(str(e))

    (auth, role, pin) = meetme_authenticate(agi, meetme)

    if not auth:
        agi.dp_break("Conference room authentication failed (id: %s, name: %s, confno: %s)"
                        % (meetme.meetmeid, meetme.name, meetme.confno))

    if meetme_exceed_max_number(agi, meetme, role):
        # TODO: Change sound by conf-maxuserexceeded
        agi.appexec('Playback', "conf-locked&vm-goodbye")
        agi.dp_break("Unable to join the conference room, max number of users exceeded "
                     "(max number: %s, id: %s, confno: %s)"
                     % (meetme.maxusers, meetme.meetmeid, meetme.confno))

    options = meetme_set_options(agi, meetme, role)

    meetme_set_diaplan_vars(agi, meetme, pin, role, options)

agid.register(incoming_meetme_set_features)
