# -*- coding: utf-8 -*-
# Copyright 2018 JDG <www.yunside.com>
# Created by YGJ <guojian.ye@yunside.com> at 2018/9/5
# ========系统参数========
# jadedragon.notify.channel.md.url:网关
# jadedragon.notify.channel.md.user:账号
# jadedragon.notify.channel.md.pwd:密码
# =======================
import logging
import urllib
from odoo import models, api
from odoo import tools
import datetime
import threading
import requests
import hashlib

_logger = logging.getLogger(__name__)

ERROR_MAP = {
    '-1': "短信平台URL不正确",
    '-2': "短信平台帐号/密码不正确",
    '-4': "短信平台余额不足支持本次发送",
    '-5': "短信内容数据格式错误",
    '-6': "短信接口调用参数有误",
    '-7': "短信平台权限受限",
    '-8': "短信平台流量控制错误",
    '-9': "短信平台扩展码权限错误",
    '-10': "短信内容内容长度过长",
    '-11': "短信平台内部数据库错误",
    '-12': "短信平台序列号状态错误",
    '-14': "短信平台服务器写文件失败",
    '-17': "短信平台没有权限",
    '-19': "短信平台禁止同时使用多个接口地址",
    '-20': "相同手机号，相同短信内容重复提交",
    '-21': "短信平台Ip鉴权失败",
    '-22': "短信平台Ip鉴权失败",
    '-23': "短信平台缓存无此序列号信息",
    '-601': "短信平台序列号为空，参数错误",
    '-602': "短信平台序列号格式错误，参数错误",
    '-603': "短信平台密码为空，参数错误",
    '-604': "短信平台手机号码为空，参数错误",
    '-605': "短信内容为空，参数错误",
    '-606': "短信参数ext长度大于9，参数错误",
    '-607': "短信平台参数错误 扩展码非数字 ",
    '-608': "短信平台参数错误 定时时间非日期格式",
    '-609': "短信平台rrid长度大于18,参数错误 ",
    '-610': "短信平台参数错误 rrid非数字",
    '-611': "短信平台参数错误 内容编码不符合规范",
    '-623': "短信平台手机个数与内容个数不匹配",
    '-624': "短信平台扩展个数与手机个数不匹配",
    '-625': "短信平台定时时间个数与手机个数不匹配",
    '-626': "短信平台rrid个数与手机个数不匹配",
}


def encode_md5(str):
    if not str:
        return str
    m = hashlib.md5()
    m.update(str)
    return m.hexdigest()


class SMSThread(threading.Thread):
    def __init__(self, sms_url, sms_user, sms_pwd, mobile, content, ext, sms_sign):
        threading.Thread.__init__(self)
        self.sms_url = sms_url
        self.sms_user = sms_user
        self.sms_pwd = sms_pwd
        self.mobile = mobile
        self.content = content
        self.sms_sign = sms_sign
        self.ext = ext

    def run(self):
        text = self.content + '【%s】' % self.sms_sign
        text = text.encode('utf-8')
        request_data = {
            'sn': self.sms_user,
            'pwd': encode_md5(self.sms_user + self.sms_pwd).upper(),
            'mobile': self.mobile,
            'content': text,
            'ext': self.ext
        }
        _logger.info('%s?username=%s&password=%s&%s' % (self.sms_url, "******", "**********", request_data))
        try:
            response = requests.post(url=self.sms_url, data=request_data,
                                     headers={'content-type': 'application/x-www-form-urlencoded'})
            result_text = response.text
            if result_text and result_text.isdigit() and int(result_text) > 0:
                _logger.info('send sms success.')
                return {'result': True, 'result_text': '短信发送成功！'}
            else:
                _logger.info('send sms failed. error code %s' % (ERROR_MAP.get(result_text),))
                return {'result': False, 'result_text': '短信发送失败，错误信息为：%s' % ERROR_MAP.get(result_text)}
        except Exception as e:
            _logger.error('send sms error: %s', e.message)
            return {'result': False, 'result_text': '短信发送失败，错误信息为：%s' % e.message}


class JDGNotifyChannelMDSBT(models.AbstractModel):
    _name = 'jd.notify.channel.md.sbt'
    _description = u'玉龙科技漫道短信发送通道'

    @api.multi
    def get_sms_param(self):
        url_rec = self.env['ir.config_parameter'].sudo().get_param("jadedragon.notify.channel.md.sbt.url")
        if not url_rec or url_rec == 'False':
            _logger.warning(u'未配置漫道短信网关，请联系技术人员进行配置！')
            raise Exception(u'未配置漫道短信网关，请联系技术人员进行配置！')
        else:
            sms_url = url_rec

        user_rec = self.env['ir.config_parameter'].sudo().get_param("jadedragon.notify.channel.md.sbt.user")
        if not user_rec or user_rec == 'False':
            _logger.warning(u'未配置漫道短信网关登录用户，请联系技术人员进行配置！')
            raise Exception(u'未配置漫道短信网关登录用户，请联系技术人员进行配置！')
        else:
            sms_user = user_rec

        pwd_rec = self.env['ir.config_parameter'].sudo().get_param("jadedragon.notify.channel.md.sbt.pwd")
        if not pwd_rec or pwd_rec == 'False':
            _logger.warning(u'未配置漫道短信网关登录密码，请联系技术人员进行配置！')
            raise Exception(u'未配置漫道短信网关登录密码，请联系技术人员进行配置！')
        else:
            sms_pwd = pwd_rec

        ext_rec = self.env['ir.config_parameter'].sudo().get_param("jadedragon.notify.channel.md.sbt.ext")
        if not ext_rec or ext_rec == 'False':
            _logger.warning(u'未配置漫道短信网关扩展参数，请联系技术人员进行配置！')
            raise Exception(u'未配置漫道短信网关扩展参数，请联系技术人员进行配置！')
        else:
            sms_ext = ext_rec

        sign_rec = self.env['ir.config_parameter'].sudo().get_param("jadedragon.notify.channel.md.sbt.sign")
        if not sign_rec or sign_rec == 'False':
            _logger.warning(u'未配置漫道短信网关签名参数，请联系技术人员进行配置！')
            raise Exception(u'未配置漫道短信网关签名参数，请联系技术人员进行配置！')
        else:
            sms_sign = sign_rec
        return sms_url, sms_user, sms_pwd, sms_ext, sms_sign

    @api.multi
    def send_async(self, mobile=None, text=None):
        """
        漫道短信异步接口。
        :param mobile:
        :param text:
        :return:
        """
        if (not mobile) or (not text):
            _logger.warning('mobile or text is empty.')
        sms_url, sms_user, sms_pwd, sms_ext, sms_sign = self.get_sms_param()
        if sms_url == 'False' or sms_pwd == 'False' or sms_user == 'False':
            _logger.warning("未配置漫道短信网关相关信息，请联系技术人员进行配置！")
            raise Exception("未配置漫道短信网关相关信息，请联系技术人员进行配置！")

        if True:
            SMSThread(sms_url, sms_user, sms_pwd, mobile, text, sms_ext, sms_sign).start()
            self.env['jd.notify.channel.message.io'].insert_rec('sms', mobile, text, 'success')
            return {'result': True, 'result_text': '短信发送成功！'}
        else:
            _logger.warning("ignore sms to %s" % mobile)
            _logger.warning("Do not sent sms, Because you are not in prod environment.")
            return {'result': False, 'result_text': '非生产环境不发送短信！'}

    @api.multi
    def send_sync(self, mobile=None, text=None):
        """
        漫道短信同步接口。
        :param mobile:
        :param text:
        :return:
        """
        if (not mobile) or (not text):
            _logger.warning('mobile or text is empty.')

        sms_url, sms_user, sms_pwd, sms_ext, sms_sign = self.get_sms_param()

        if sms_url == 'False' or sms_pwd == 'False' or sms_user == 'False':
            _logger.warning("未配置漫道短信网关相关信息，请联系技术人员进行配置！")
            raise Exception("未配置漫道短信网关相关信息，请联系技术人员进行配置！")

        if True:
            text += '【%s】' % sms_sign
            text = text.encode('utf-8')
            request_data = {
                'sn': sms_user,
                'pwd': encode_md5(sms_user + sms_pwd).upper(),
                'mobile': mobile,
                'content': text,
                'ext': sms_ext
            }
            _logger.info('%s?username=%s&password=%s&%s' % (sms_url, "******", "**********", request_data))
            try:
                response = requests.post(url=sms_url, data=request_data,
                                         headers={'content-type': 'application/x-www-form-urlencoded'})
                result_text = response.text
                if result_text and result_text.isdigit() and int(result_text) > 0:
                    _logger.info('send sms success.')
                    self.env['jd.notify.channel.message.io'].insert_rec('sms', mobile, text, 'success')
                    return {'result': True, 'result_text': '短信发送成功！'}
                else:
                    _logger.info('send sms failed. error code %s' % (ERROR_MAP.get(result_text),))
                    self.env['jd.notify.channel.message.io'].insert_rec('sms', mobile, text, 'failed',
                                                                        '短信发送失败，错误信息为：%s' % ERROR_MAP.get(result_text))
                    return {'result': False, 'result_text': '短信发送失败，错误信息为：%s' % ERROR_MAP.get(result_text)}
            except Exception as e:
                _logger.error('send sms error: %s', e.message)
                self.env['jd.notify.channel.message.io'].insert_rec('sms', mobile, text, 'failed',
                                                                    '短信发送失败，报错信息为：%s' % e.message)
                return {'result': False, 'result_text': '短信发送失败，报错信息为：%s' % e.message}
        else:
            _logger.warning("ignore sms to %s" % mobile)
            _logger.warning("Do not sent sms, Because you are not in prod environment.")
            return {'result': False, 'result_text': '非生产环境不发送短信！'}
