import websockets
import datetime
import hashlib
import base64
import hmac
import json
from urllib.parse import urlencode
from wsgiref.handlers import format_date_time
from datetime import datetime
from time import mktime
from config import Config

def generate_xf_asr_url():
    #设置讯飞流式听写API相关参数
    APIKey = Config.XF_ASR.API_KEY
    APISecret = Config.XF_ASR.API_SECRET

    #鉴权并创建websocket_url
    url = 'wss://ws-api.xfyun.cn/v2/iat'
    now = datetime.now()
    date = format_date_time(mktime(now.timetuple()))
    signature_origin = "host: " + "ws-api.xfyun.cn" + "\n"
    signature_origin += "date: " + date + "\n"
    signature_origin += "GET " + "/v2/iat " + "HTTP/1.1"
    signature_sha = hmac.new(APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
                                digestmod=hashlib.sha256).digest()
    signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
    authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
        APIKey, "hmac-sha256", "host date request-line", signature_sha)
    authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
    v = {
        "authorization": authorization,
        "date": date,
        "host": "ws-api.xfyun.cn"
    }
    url = url + '?' + urlencode(v)
    return url


def make_first_frame(buf):
    first_frame = {"common" : {"app_id":Config.XF_ASR.APP_ID},"business" : {"domain":"iat","language":"zh_cn","accent":"mandarin","vinfo":1,"vad_eos":1000},
                   "data":{"status":0,"format":"audio/L16;rate=16000","audio":buf,"encoding":"raw"}}
    return json.dumps(first_frame)

def make_continue_frame(buf):
    continue_frame = {"data":{"status":1,"format":"audio/L16;rate=16000","audio":buf,"encoding":"raw"}}
    return json.dumps(continue_frame)

def make_last_frame(buf):
    last_frame = {"data":{"status":2,"format":"audio/L16;rate=16000","audio":buf,"encoding":"raw"}}
    return json.dumps(last_frame)

def parse_xfasr_recv(message):
    code = message['code']
    if code!=0:
        raise Exception("讯飞ASR错误码："+str(code))
    else:
        data = message['data']['result']['ws']
        result = ""
        for i in data:
            for w in i['cw']:
                result += w['w']
        return result
    
async def xf_asr_websocket_factory():
    url = generate_xf_asr_url()
    return await websockets.connect(url)