#!/usr/bin/env python
# encoding=utf-8

import sys
import six
import base64

from django.db import models
from django.core.management import BaseCommand
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from Crypto.Cipher import AES

from api.models import Doctor

from gm_upload import ImgUrlField, IMG_TYPE

#####  修改 测试环境和线上环境密钥不同,导致数据读取问题 ##############

class PhoneServiceRecord1(models.Model):
    class Meta:
        verbose_name = u'通话录音数据'
        db_table = 'api_phone_service_record'
        app_label = 'api'

    doctor = models.ForeignKey(Doctor, verbose_name=u"城市ID", help_text=u"城市ID", null=True)
    call_phone = models.CharField(max_length=20, verbose_name="主叫号码", null=True, blank=True, default='')
    dest_phone = models.CharField(max_length=20, verbose_name="被叫号码", null=True, blank=True, default='')
    call_time = models.DateTimeField(null=True, blank=True, verbose_name='呼叫时间')
    transfer_phone = models.CharField(max_length=10, verbose_name="分机号码", null=True, blank=True, default='')
    call_status = models.IntegerField(default=0, verbose_name=u'接听状态')
    audio_url = ImgUrlField(img_type=IMG_TYPE.AUDIO, max_length=120, verbose_name='音频地址', blank=True, default='')
    duration = models.IntegerField(default=0, verbose_name=u'通话时长')


class Command(BaseCommand):

    def handle(self, *args, **options):
        crypto_right = AESCrypto()
        crypto_test = AESCrypto(key='keycasefornonprd',iv='iv_casefornonprd')

        phone_services = PhoneServiceRecord1.objects.filter()
        for phone_service in phone_services:
            is_need_save = False
            call_phone = phone_service.call_phone
            dest_phone = phone_service.dest_phone
            call_phone = try_decrypt_phone(crypto_right, crypto_test, call_phone, phone_service.id)
            dest_phone = try_decrypt_phone(crypto_right, crypto_test, dest_phone, phone_service.id)
            if call_phone:
                phone_service.call_phone = call_phone
                is_need_save = True
            if dest_phone:
                phone_service.dest_phone = dest_phone
                is_need_save = True
            if is_need_save:
                phone_service.save()


def try_decrypt_phone(crypto_right, crypto_test, phone, phone_service_id):
    if phone.startswith(AESCrypto.prefix):
        try:
            crypto_right.decrypt(phone[len(AESCrypto.prefix):])
            return ''
        except:
            try:
                call_phone = crypto_test.decrypt(phone[len(AESCrypto.prefix):])
                call_phone = AESCrypto.prefix + crypto_right.encrypt(call_phone)
                return call_phone
            except:
                print "can not crypto phone_service_id:",phone_service_id
                return ''
    else:
        return ''


class AESCrypto(object):
    prefix = 'enc_str:::'

    def __init__(self, key=None, iv=None):
        self.key = key or settings.AES_KEY
        self.iv = iv or settings.AES_IV

    def get_crypt_object(self, type_='enc'):
        if type_ == 'enc':
            return AES.new(self.key, AES.MODE_CFB, self.iv)
        elif type_ == 'dec':
            return AES.new(self.key, AES.MODE_CFB, self.iv)
        else:
            raise ImproperlyConfigured('unsupport crypt type %s' % (crypt_type))

    def encrypt(self, text):
        self._enc_obj = self.get_crypt_object('enc')
        if sys.version_info < (3, ):
            if type(text) == six.types.UnicodeType:
                text = text.encode('utf-8')
        encrypted = self._enc_obj.encrypt(text)
        encrypted = base64.b64encode(encrypted)
        return encrypted

    def decrypt(self, crypted):
        self._dec_obj = self.get_crypt_object('dec')
        crypted = base64.b64decode(crypted)
        text = self._dec_obj.decrypt(crypted)
        if sys.version_info < (3, ):
            try:
                text = text.decode('utf-8')
            except:
                raise Exception
        return text
