# -*- coding: utf-8 -*-
######################################################################################################
#
# Copyright (C) B.H.C. sprl - All Rights Reserved, http://www.bhc.be
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
# including but not limited to the implied warranties
# of merchantability and/or fitness for a particular purpose
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>
######################################################################################################

import urllib
import httplib    
import json
import urllib
import urllib2
from openerp.exceptions import RedirectWarning, UserError, ValidationError
from openerp.osv import fields, osv, expression

import base64
from openerp.addons.foundation.JSONRequest import JSONRequest
import re
import logging
from datetime import datetime
from openerp import models, fields, api, _
from lib2to3.fixer_util import Number
import code
_logger = logging.getLogger(__name__)
import time
import unicodedata
from xml.dom.minidom import Node
from xml.dom.minidom import parse, parseString
import xml.dom.minidom
from openerp import tools

# main mako-like expression pattern
EXPRESSION_PATTERN = re.compile('(\$\{.+?\})')


class sms_compose_message(models.TransientModel):
    _name = 'smscompose.message'
    #_inherit = ['mail.message']
    _log_access = True

    @api.model
    def default_get(self, fields):
        res = super(sms_compose_message, self).default_get(fields)
        move = self.env['res.partner'].browse(self._context.get('active_ids'))
        number = []
        n = []
        for i in move:
            if i.mobile :
                number.append(str(i.mobile))
        if 'number' in fields:
            res.update({'number': number})
        return res

    number = fields.Char(string='phone')
    number_t = fields.Char(string='phone', )
    message = fields.Text(string='Message',required=True)
    template = fields.Many2one('mail.template',string='Tempate SMS')
    channel_ids = fields.Many2many('mail.channel', 'mail_message_mail_channel_rel2', string='Channels')
    needaction_partner_ids = fields.Many2many('res.partner', 'mail_message_res_partner_needaction_rel2', string='Need Action')
    starred_partner_ids = fields.Many2many('res.partner', 'mail_message_res_partner_starred_rel2', string='Favorited By')

    @api.onchange('template')
    def onchange_temp(self):
        if self.template:
            self.number_t = self.template.number
            self.message = self.template.content

    @api.one
    def sendSMS(self):
        self.action_sendSMS(self.number,self.message)
        
    @api.one    
    def action_sendSMS(self,number,message):
        if not number:
            #self.template.state = 'notsend'
            raise ValidationError(_('No Mobile\'s information for send SMS'))
        active_ids = self._context.get('active_ids')
        part_obj = self.env['res.partner']
        msg_obj = self.env['message.message']
        sms = []
        for res_id in part_obj.browse(active_ids):
            if self.template :
                print "ok"
                sms_dict = self.render_message_batch_sms(res_id)
                print "sms_dict[0][res_id.id]['body']" , sms_dict[0][res_id.id]['body']
                print "ms_dict[0][res_id.id]['number']" , sms_dict[0][res_id.id]['number']
                print "ok 2"
                self.Send(sms_dict[0][res_id.id]['number'], sms_dict[0][res_id.id]['body'])
                print "ici"
            elif ("," in number):
                num= number
                number = number.replace(' ','')
                number = number.split(',')
                for i in number :
                    number = i
                    self.Send(number,message)
            else:
                self.Send(number,message)
            
        return True


    @api.one
    def Send(self,number,message):
        message = unicodedata.normalize('NFKD', message).encode('ASCII', 'ignore').decode('ASCII')
        connect_obj = self.env['connect.connect']
        connect_id = connect_obj.search([('type', '=', "sending")])
        if connect_id:
            try:
                connect_rec = connect_id[0]
            except:
                raise ValidationError(_('Sending configuration not created!'))
            password = str(connect_rec.password)
            registration_id = connect_rec.registration_id
            username = str(connect_rec.username)
            if number[0] == "+":
                number = urllib.urlencode({'number': number})
                number1 = number.split('=')
                number = number1[1]
                number = number.replace(' ', '')
            elif number[0] == "0":
                raise ValidationError(_(
                    'The phone number must be formated like this: + followed by country operator followed by the numbers without characters. e.g. : +3265698745'))
            message = message.decode('UTF-8')
            message = urllib.urlencode({'message': message})
            msg = message.split('=')
            message = msg[1]
            url = str(connect_rec.url)
            url += '?method=sendText&username=' + username + '&password=' + password + '&destinationAddress=' + number + '&originatingAddress=&operatorid=0&paycode=0&msgtext=' + message + '&serviceid=' + registration_id + '&method=sendText'
            values = {'password': password,
                      'destinationAddress': number,
                      }
            try:
                data = urllib.urlencode(values)
                req = urllib2.Request(url, data)
                handle = urllib2.urlopen(req)
                the_page = handle.read()
            except:
                raise ValidationError(_('Your Configuration is invalid !'))
            try:
                ResponsePreamble = xml.dom.minidom.parseString(the_page)
                ticket = self.getText((ResponsePreamble.getElementsByTagName("TICKET")[0]).childNodes)
                if ticket:
                    self.history(ticket)
            except:
                print "no num for SMS"
        else:
            raise osv.except_osv('Your Configuration is not created!')

    @api.one
    def history(self,ticket):
        active_ids = self._context.get('active_ids')
        part_obj=self.env['res.partner']
        msg_obj=self.env['message.message']
        sms=[]
        for res_id in part_obj.browse(active_ids):
            if not self.template:
                msg=msg_obj.create({'number':res_id.mobile,'message':self.message,'template':self.template and self.template.id or False,
                                    'partner_id':res_id.id,'state':'sent','datime':datetime.now(),'mess_id': ticket})
                sms.append(msg)
            else:
                sms_dict = self.render_message_batch_sms(res_id)
                msg=msg_obj.create({'number':sms_dict[0][res_id.id]['number'],'message':sms_dict[0][res_id.id]['body'],'template':self.template.id,
                                    'partner_id':res_id.id,'state':'sent','datime':datetime.now(),'mess_id': ticket})
                sms.append(msg)
            
    def getText(self,nodelist):
        rc = []
        for node in nodelist:
            if node.nodeType == node.TEXT_NODE:
                rc.append(node.data)
        return ''.join(rc)

    @api.one
    def render_template_batch_sms(self, fields, template, model, res_ids):
        results = dict.fromkeys(res_ids, False)
        for res_id in res_ids:
            def merge(match):
                exp = str(match.group()[2:-1]).strip()
                result = eval(exp, {
                    'user': self.env['res.users'].browse(self._uid),
                    'object': res_id,
                })
                return result and tools.ustr(result) or ''

            results[res_id.id] = fields and EXPRESSION_PATTERN.sub(merge, fields)
        return results

    @api.one
    def render_message_batch_sms(self, res_ids):
        number = self.render_template_batch_sms(self.number, self.template,
                                                self.template and self.template.model_id.model, res_ids)
        print "number" , number
        bodies = self.render_template_batch_sms(self.message, self.template,
                                                self.template and self.template.model_id.model, res_ids)
        print "bodies' " , bodies
        results = {}
        for res_id in res_ids:
            results[res_id.id] = {
                'number': number[0][res_id.id],
                'body': bodies[0][res_id.id],
            }
        return results