import datetime
import json
import logging
import math
import os
import time

import requests
import xml.etree.ElementTree as ET
from domain.imdb.value_object import CelebrityRoleValue
from domain.injector.value_object import DefinitionValue, TaskModelActionValue, ContentTypeValue
from domain.lsp.base_injector import LspInjectorC2, TaskStatusValue, C2ApiUtil, TaskModel
from imdb.models import CelebrityMediaRelationModel
from utils.date_utils import datetime_now_minsecond, datetime_now
from lxml import etree
from injector.models import MediaInfoSyncModel
from domain.lsp.generated.common_xsd import Adi
from domain.lsp.value_object import C2ApiUtil, CodeSampleFactory
from domain.injector.task_queue import TaskQueue
from django.db.models import F
import pypinyin
import json
from domain.injector.task_queue import TaskCDNLOCK

logger = logging.getLogger(__file__)


class JiangXiYd(LspInjectorC2):
    Media_Required_Args = ("episodes", "name", "date_published", "category", "genres", "regions",
                           "storyline", "seconds", "total_seconds", "languages", "year", "douban_score")
    MediaExt_Required_Args = ("media_horpic", "definition")

    Video_Required_Args = ("a_codec", "definition")

    Episode_Required_Args = ("serial_num",)

    def __init__(self, alias="JIANGXIYD"):
        super().__init__(alias)
        self.csp_id = self.conf.csp_id
        self.lsp_id = self.conf.lsp_id
        self.csp_id_hw = "SYWHOTT"
        self.csp_id_zx = "SYWH"
        self.lsp_id_hw = "SYWHOTT"
        self.lsp_id_zx = "SYWHzte"
        self.cast_sep = ";"
        self.region_sep = ";"
        self.genre_sep = ""
        self.tag_sep = ";"
        # self.is_cdn_xml = False
        # self.proxy_hw = False  # 额外加参数控制状态
        # self.content_provider = "森宇童梦视界"
        # self.cdn_ftp_url = "ftp://shsytmsj:UvtHM28SrznJZv37@112.25.63.183:2111/{}/{}"
        self.code_factory = CodeSampleFactory(30)
        self.code_factory_wl = CodeSampleFactory("sywl", 28)
        # self.EXPIRE_TIME = 3600 * 24 * 3
        self.cdn_url_zx = "http://117.169.45.227:8502/cmsgw/services/ctms"
        self.cdn_url_hw = "http://117.169.45.227:8502/cmsgw/services/ctms"

    def get_media_name(self, name):
        return str(name).strip()

    def gen_media_definition(self, definition):
        if definition == "1":
            return "LD"
        elif definition == "2":
            return "SD"
        elif definition == "3":
            return "HD"
        elif definition == "4":
            return "XD"
        elif definition == "5":
            return "4K"

    def _get_positive(self, media_storage):
        return media_storage.content_type

    def gen_ftp_pic_url(self, media_id, pic_url):
        # file_name = pic_url.split("/")[-1]
        # return self.cdn_ftp_url.format(media_id, file_name)
        return pic_url

    def gen_ftp_movie_url(self, media_id, video_url):
        # file_name = "/".join(video_url.split("/")[-2:])
        # return self.cdn_ftp_url.format(media_id, file_name)
        return video_url

    def transform_chinese_to_letter(self, the_str):
        _letter = pypinyin.pinyin(the_str, style=pypinyin.FIRST_LETTER)
        result = [str(_letter[index][0]).lower() for index, _ in enumerate(_letter)]
        return "".join(result)

    def gen_date_published(self, date_published):
        if date_published:
            return str(date_published)
        return ""

    def gen_series_obj(self, _id, media, media_ext, storage, action):
        actors, directors, writers = self.get_media_person(media, actor=4, director=4, writer=2)
        vst, vet = self.get_media_effective_time_line(media.id)
        param_dict = {"category": media.category, "is_charge": 1}
        change_fields = self.injected_change.get_injected_fields(media.id, self.lsp_pk, param_dict)
        media_verpic = self.image_resize.get_oss_resize_params(self.partner_alias, media_ext.media_verpic,
                                                               size=media_ext.verpic_size, to_ip=True)

        media_horpic = self.image_resize.get_oss_resize_params(self.partner_alias, media_ext.media_horpic,
                                                               size=media_ext.horpic_size, to_ip=True)

        property_list = [
            {"ActorDisplay": directors},
            {"Definition": self.gen_definition(media_ext.definition)},
            {"PictureURL1": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_verpic))},
            {"VerticalPoster": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_verpic))},
            {"Name": self.get_media_name(self.get_media_name_by_alias(media))},
            {"Pinyin": self.transform_chinese_to_letter(self.get_media_name_by_alias(media))},
            {"Language": media.languages},
            {"WriterDisplay": actors},
            {"Description": media.storyline},
            {"EnName": self.transform_chinese_to_letter(self.get_media_name_by_alias(media))},
            {"OrgAirDate": self.gen_date_published(media.date_published)},
            {"Type": self._get_category_desc(change_fields["category"])},
            {"ProgramType": self._get_category_desc(change_fields["category"])},
            {"ProgramType2": self.get_genre(media)},
            {"ReleaseYear": media.year},
            {"VolumnCount": media.episodes},
            {"OriginalCountry": self.get_regions(media)},
            {"Tag": self.get_genre(media)},
            {"Score": media.douban_score},
            {"Duration": int(media.total_seconds)},
            # {"ContentType": "Video"},
            # {"IfPreview": self._get_positive(storage)},
            # {"IsSeries": 0 if media.episodes == 1 else 1},
            # {"Status": 1},
            {"Recommendation": media_ext.focus},
            # {"ScriptWriter": writers},
            {"IsCharge": change_fields["is_charge"]},
            # {"ProductCode": "003022cp0001"},
            {"HorizontalPoster": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_horpic))},
            # {"PictureURL2": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_horpic))},
            {"CopyRightBeginDate": vst},
            {"CopyRightEndDate": vet}
        ]

        data = {
            "element_type": "Series",
            "id": _id,
            "code": _id,
            "action": "REGIST",
            "property": property_list
        }
        return data

    def gen_definition(self, definition):

        if definition in (DefinitionValue.K4, DefinitionValue.P3840, DefinitionValue.P4096):
            return "4K"
        if definition == DefinitionValue.P480:
            return "SD"
        if definition == DefinitionValue.P720:
            return "HD"
        if definition == DefinitionValue.P1080:
            return "XD"

    def gen_program_obj(self, _id, media, media_ext, storage, episode, action):
        param_dict = {"category": media.category, "is_charge": 1}
        change_fields = self.injected_change.get_injected_fields(media.id, self.lsp_pk, param_dict)
        episode_title = self.get_episode_title(media, episode)
        media_horpic = self.image_resize.get_oss_resize_params(self.partner_alias, media_ext.media_horpic,
                                                               size=media_ext.horpic_size, to_ip=True)
        media_verpic = self.image_resize.get_oss_resize_params(self.partner_alias, media_ext.media_verpic,
                                                               size=media_ext.verpic_size, to_ip=True)
        actors, directors, writers = self.get_media_person(media, actor=4, director=4, writer=2)

        property_list = [
            {"ActorDisplay": actors},
            {"Definition": self.gen_definition(storage.definition)},
            {"PictureURL1": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_verpic))},
            {"Name": episode_title},
            {"Language": media.languages},
            {"WriterDisplay": writers},
            {"Description": media.storyline},
            {"PictureURL1": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_verpic))},
            # {"OrgAirDate": self.gen_date_published(media.date_published)},
            {"ReleaseYear": media.year},
            {"OriginalCountry": self.get_regions(media)},
            {"ProgramType": self._get_category_desc(change_fields["category"])},
            {"ProgramType2": self.get_genre(media)},
            {"VolumnCount": episode.serial_num},
            {"Duration": math.ceil(media.seconds/60)},
            # {"IsCharge": change_fields["is_charge"]},
            {"Tag": self.get_genre(media)},
            # {"IfPreview": self._get_positive(storage)},
            # {"IsSeries": 0 if media.episodes == 1 else 1},
            # {"Status": 1},
            # {"BitId": self.gen_program_definition(storage.definition, storage.v_codec)},
            # {"IsCharge": change_fields["is_charge"]},
            {"PictureURL2": self.gen_ftp_pic_url(media.id, self.to_ip_url(media_horpic))},
        ]

        data = {
            "element_type": "Program",
            "id": _id,
            "code": _id,
            "action": action,
            "property": property_list
        }
        return data

    def gen_movie_ftp_url(self, media_id, url):
        s2 = str(url).split("/")[-2]
        s1 = str(url).split("/")[-1]
        file_name = "{}/{}".format(s2, s1)
        return self.cdn_ftp_url.format(media_id, file_name)

    def gen_movie_obj(self, _id, media, storage, action, args):
        seriesId, programId, movieId = args

        file_name = storage.url.split("/")[-1]

        ext_info = {
            "cdnPlayInfos": [
                {"cdnId": "58",  # 中兴
                 "playUrl": f"http://shsymedia.jxa.bcs.ottcn.com:8080/140000000161/{movieId}/{file_name}"},
                {"cdnId": "136", "playUrl": f"http://ip:port/icntv/{programId}"},  # 136 华为能力平台
            ]
        }

        property_list = [
            {"FileURL": f"http://shsymedia.jxa.bcs.ottcn.com:8080/140000000161/{movieId}/{file_name}"},
            {"PlayURL": f"http://shsymedia.jxa.bcs.ottcn.com:8080/140000000161/{movieId}/{file_name}"},
            {"Definition": self.gen_definition(storage.definition)},
            {"CdnPlatform": "58"},
            {"Dispatch": 0},
            {"IsTranscode": 0},
            {"Md5": storage.md5},
            {"extInfo": json.dumps(ext_info)}
        ]

        data = {
            "element_type": "Movie",
            "id": _id,
            "code": _id,
            "action": action,
            "property": property_list
        }
        return data

    def gen_sub_program(self, media, media_ext, storage, episode, action, args):
        # seriesId_hw, programId_hw, movieId_hw, seriesId_zx, programId_zx, movieId_zx = args
        # psid = seriesId_hw
        # ppid = programId_hw
        # pmid = movieId_hw
        psid = self.code_factory_wl.gen_series_code(media.id)
        ppid = self.code_factory_wl.gen_program_code(episode.id)
        pmid = self.code_factory_wl.gen_movie_code(storage.id)

        series_obj = self.gen_series_obj(psid, media, media_ext, storage, action)
        program_obj = self.gen_program_obj(ppid, media, media_ext, storage, episode, action)
        movie_obj = self.gen_movie_obj(pmid, media, storage, action, args)
        series_program_mapping = self.property_mapping("Series", "Program", psid, ppid, sequence=episode.serial_num,
                                                       action=action)
        program_movie_mapping = self.property_mapping("Program", "Movie", ppid, pmid, action=action)

        data = {
            "BizDomain": "2",
            "object_list": [series_obj, program_obj, movie_obj],
            "mapping_list": [series_program_mapping, program_movie_mapping]
        }
        return data

    def program(self, cmd_id, action, *args):
        # seriesId_hw, programId_hw, movieId_hw, seriesId_zx, programId_zx, movieId_zx = args

        task_id = cmd_id.split("_")[0]
        task = TaskModel.objects.filter(pk=task_id).select_related("media", "storage", "episode").first()
        media = task.media
        media_ext = media.mediaextfieldmodel
        storage = task.storage
        episode = task.episode
        data = self.gen_sub_program(media, media_ext, storage, episode, action, args)
        xml = Adi.to_xml(data, flag="Nope")
        return xml

    def post_api(self, correlate_id, cmd_id):
        headers = {"content-type": "text/xml", "SOAPAction": "application/soap+xml;charset=utf8"}
        ftp_url = self.get_cmd_ftp_url(self.csp_id, cmd_id)
        data = C2ApiUtil.REQUESTXML.format(self.csp_id, self.lsp_id, correlate_id, ftp_url)
        logging.warning("{} exec_sync_header_cmd HEADER_ID: {}, Request: {}".format(self.lsp_id, cmd_id, data))
        try:
            content = requests.post(self.conf.cms_api, headers=headers, data=data).content
            logging.warning("{} exec_sync_header_cmd HEADER_ID: {}, Response: {}".format(self.lsp_id, cmd_id, content))
            tree = etree.fromstring(content)
            code = tree.find(".//Result").text.strip()
            msg = ""
        except Exception as e:
            logging.error("exception:{}".format(e))
            code = -1
            msg = str(e)
        return code, msg

    def exec_cmd(self, task_id, cmd_id):
        correlate_id = self.generate_correlate_id(task_id, "common", datetime_now())
        code, msg = self.post_api(correlate_id, cmd_id)
        if str(code) == "0":
            status = TaskStatusValue.INFO_TRANSFERING
            msg = ""
        else:
            status = TaskStatusValue.INFO_FAILED

        TaskModel.objects.filter(pk=task_id).update(status=status, remark=msg)
        return status

    def property_cdn_series(self, media, psid, vst, vet, _type, action):

        search_name = self.transform_chinese_to_letter(self.get_media_name_by_alias(media))
        data = {
            "element_type": "Series",
            "id": psid,
            "code": psid,
            "action": action,
            "property": [
                {"Name": self.get_media_name_by_alias(media)},
                {"SearchName": search_name},
                {"Type": _type},
                {"ReleaseYear": media.year},
                {"Status": 1},
                {"LicensingWindowStart": vst},
                {"LicensingWindowEnd": vet},
                {"Result": 0},
            ]
        }
        return data

    def property_cdn_zx_series(self, media, psid, vst, vet, _type, action):

        search_name = self.transform_chinese_to_letter(self.get_media_name_by_alias(media))
        data = {
            "element_type": "Series",
            "id": psid,
            "code": psid,
            "action": action,
            "property": [
                {"Name": self.get_media_name_by_alias(media)},
                {"SearchName": search_name},
                {"Type": _type},
                {"ReleaseYear": media.year},
                {"VolumnCount": media.episodes},
                {"Status": 1},
                {"LicensingWindowStart": vst},
                {"LicensingWindowEnd": vet},
                {"Result": 0},
            ]
        }
        return data

    def property_cdn_program(self, ppid, media, vst, vet, _type, action):

        search_name = self.transform_chinese_to_letter(self.get_media_name_by_alias(media))

        data = {
            "element_type": "Program",
            "id": ppid,
            "code": ppid,
            "action": action,
            "property": [
                {"Name": self.get_media_name_by_alias(media)},
                {"SearchName": search_name},
                {"Type": _type},
                {"ReleaseYear": media.year},
                {"Status": 1},
                {"LicensingWindowStart": vst},
                {"LicensingWindowEnd": vet},
                {"Result": 0},
            ]
        }

        return data

    def property_cdn_zx_program(self, ppid, media, vst, vet, _type, action):

        search_name = self.transform_chinese_to_letter(self.get_media_name_by_alias(media))

        data = {
            "element_type": "Program",
            "id": ppid,
            "code": ppid,
            "action": action,
            "property": [
                {"Name": self.get_media_name_by_alias(media)},
                {"SearchName": search_name},
                {"Genre": self.get_genre(media)},
                {"Type": _type},
                {"ReleaseYear": media.year},
                {"Status": 1},
                {"LicensingWindowStart": vst},
                {"LicensingWindowEnd": vet},
                {"Result": 0},
            ]
        }

        return data

    def property_cdn_movie(self, pmid, storage, action):
        data = {
            "element_type": "Movie",
            "id": pmid,
            "code": pmid,
            "action": action,
            "property": [
                {"Type": 1},
                {"FileURL": self.get_storage_ftp_url(storage.url)},
            ]
        }

        return data

    def property_cdn_zx_movie(self, pmid, storage, action):
        data = {
            "element_type": "Movie",
            "id": pmid,
            "code": pmid,
            "action": action,
            "property": [
                {"Type": 1},
                {"FileURL": self.get_storage_ftp_url(storage.url)},
            ]
        }

        return data

    def _gen_program(self, media_storage, media, episode, media_ext, action, package_show):
        vst, vet = self.get_episode_effective_time(media.id, episode.serial_num)

        psid = self.code_factory.gen_series_code(media.id)
        ppid = self.code_factory.gen_program_code(episode.id)
        pmid = self.code_factory.gen_movie_code(media_storage.id)

        param_dict = {"category": media.category, "is_charge": 1}
        change_fields = self.injected_change.get_injected_fields(media.id, self.lsp_pk, param_dict)
        _type = self._get_category_desc(change_fields["category"])

        if package_show:
            p_series = self.property_cdn_series(media, psid, vst, vet, _type, action)
            p_program = self.property_cdn_program(ppid, media, vst, vet, _type, action)
            p_movie = self.property_cdn_movie(pmid, media_storage, action=action)
        else:
            p_series = self.property_cdn_zx_series(media, psid, vst, vet, _type, action)
            p_program = self.property_cdn_zx_program(ppid, media, vst, vet, _type, action)
            p_movie = self.property_cdn_zx_movie(pmid, media_storage, action=action)

        mapping_program = self.property_mapping("Series", "Program", psid, ppid, sequence=episode.serial_num,
                                                action=action)
        mapping_movie = self.property_mapping("Program", "Movie", ppid, pmid, sequence=1, action=action)

        mapping_package_program = self.property_mapping("Package", "Program", "151000", ppid, _type=1, sequence=1,
                                                        action=action)
        if package_show:
            mapping_list = [mapping_program, mapping_movie, mapping_package_program]
        else:
            mapping_list = [mapping_program, mapping_movie]
        return {
            "domain": "2",
            "object_list": [p_series, p_program, p_movie],
            "mapping_list": mapping_list,
        }

    def save_cdn_xml(self, data, csp_id, cmd_id):
        xml = Adi.to_xml(data, flag="Nope")
        print(xml)
        # 保存xml工单
        dir_path = self.get_xml_file_dir_path()
        if not os.path.exists(dir_path):
            os.makedirs(dir_path, exist_ok=True)

        file_path = self.get_xml_file_path(csp_id.lower(), cmd_id)
        with open(file_path, "w") as f:
            f.write(xml)

    def cdn_requests(self, task, csp_id, lsp_id, cdn_url, _task_id):
        correlate_id = self.generate_correlate_id(task.id, suffix=datetime_now_minsecond())
        ftp_url = self.get_cmd_ftp_url(csp_id.lower(), _task_id)
        request_data = C2ApiUtil.REQUESTXML.format(csp_id, lsp_id, correlate_id, ftp_url)
        logging.warning("request_data:{}".format(request_data))
        headers = {
            "Content-Type": "text/xml",
            "SOAPAction": "application/soap+xml;charset=utf8"  # no SOAPAction header

        }
        resp = requests.post(cdn_url, headers=headers, data=request_data)
        logging.warning("cdn_requests HEADER_ID: {}, Response: {}".format(_task_id, resp.content))
        tree = ET.fromstring(resp.content)
        msg = tree.find(".//ErrorDescription").text.strip()
        code = tree.findall(".//multiRef")[1].text.strip()
        if code == "0":
            status_code = True
        else:
            status_code = False
        return status_code

    def cdn_injector_one(self, task, csp_id, lsp_id, cdn_url, action="REGIST", package_show=True):
        # 构建xml工单
        data = self._gen_program(task.storage, task.media, task.episode, task.media.mediaextfieldmodel, action,
                                 package_show)
        _task_id = self.generate_correlate_id(task.id)
        self.save_cdn_xml(data, csp_id.lower(), _task_id)
        # 进行requests请求
        return self.cdn_requests(task, csp_id, lsp_id, cdn_url, _task_id)

    def cdn_injector(self, task, action):
        # 访问 Task有几个，如果1个则，表示 是第一个,就带上海报地址
        hw_status = self.cdn_injector_one(task, self.csp_id_hw, self.lsp_id_hw, self.cdn_url_hw, action)
        time.sleep(0.1)
        zx_status = self.cdn_injector_one(task, self.csp_id_zx, self.lsp_id_zx, self.cdn_url_zx, action, False)

        logging.warning("hw_status: {}, zx_status:{}".format(hw_status, zx_status))

        remark = "all fail"
        if hw_status and zx_status:
            status = TaskStatusValue.FILE_TRANSFERING
            remark = "hw+zx"
        else:
            status = TaskStatusValue.FILE_FAILED
            if hw_status:
                remark = "hw"
            if zx_status:
                remark = "zx"

        task.status = status
        task.remark = remark
        task.save()
        return status

    def get_continue_to_injector(self, status):
        """获取是否继续注入流程flag，C2为一个流程,所以直接返回False"""
        return status not in TaskStatusValue.stop_injector()

    def requests_soap(self, task, action, *args):
        _task_id = self.generate_correlate_id(task.id)
        self.save_program_xml_file(self.csp_id, _task_id, action, *args)
        status = self.exec_cmd(task.id, _task_id)
        return status

    def fusion_injector(self, task, action):
        action = task.action_description()
        # 读取缓存的数据，
        psid = self.code_factory.gen_series_code(task.media_id)
        ppid = self.code_factory.gen_program_code(task.episode_id)
        pmid = self.code_factory.gen_movie_code(task.storage_id)
        args = [psid, ppid, pmid]
        _status = self.requests_soap(task, action, *args)
        t_status = _status

        return t_status

        # 进行 融合注入

    # r2 = requests.post(url, params=params_zx)
    # resp_json2 = r2.json()
    # logging.warning("resp_json_zx:{}".format(resp_json2))
    # 一会解析，只要收不到id，就不不改变状态， 消息也不去掉。一直是信息注入发起状态

    # 子集注入
    def injector(self, task, action="REGIST"):
        status = 0
        if task.status == TaskStatusValue.FILE_PENDING:
            status = self.cdn_injector(task, action)
        if task.status == TaskStatusValue.INFO_PENDING:
            status = self.fusion_injector(task, action)
        flag = self.get_continue_to_injector(status)
        return status, flag

    def update(self, task):
        status = TaskStatusValue.INFO_PENDING
        task.status = status
        task.save()
        # TaskQueue.update(task.level, task.id, status)
        self.injector(task, action="UPDATE")
        self.update_storage(task.partner_id, task.storage_id)

    def remove(self, task):
        # 要先删除融合注入，
        status = TaskStatusValue.FILE_PENDING
        task.status = status
        task.save()
        TaskQueue.update(task.level, task.id, status)
        self.injector(task, action="DELETE")
        self.off_line_storage(task.partner_id, task.storage_id)

    def remove_wl(self, task):
        status = TaskStatusValue.INFO_PENDING
        task.status = status
        task.action = 3
        task.save()
        self.fusion_injector(task, action="DELETE")

    def callback(self, request_body):
        logger.warning("{} 回执请求体内容 {}".format(self.partner_alias, request_body))
        params = C2ApiUtil.callback_params_config(self.partner_alias)
        re_cspid_id = ".//CSPID"
        re_lspid_id = ".//LSPID"
        re_correlate_id = params["correlate_id"]
        re_cmd_result = params["cmd_result"]
        re_result_file_url = params["result_fileURL"]
        re_response_xml = params["response_xml"]
        wl_response = C2ApiUtil.FUJIANYIDONG

        code = 0
        desc = "success"

        try:
            res_callback = (request_body.replace(b'soape:soapenc="http://schemas.xmlsoap.org/soap/encoding',
                                                 b'soapenc:string').replace(
                b'soapencoapenc="http://schemas.xmlsoap.org/soap/encoding/', b'soapenc:string'))
            tree = ET.fromstring(res_callback)
            cspid_id = tree.find(re_cspid_id).text
            lspid_id = tree.find(re_lspid_id).text
            _correlate_id = tree.find(re_correlate_id).text
            code = tree.find(re_cmd_result).text
            result_file_url = tree.find(re_result_file_url).text
            cor_id, flag, _ = _correlate_id.split("_")

            if cspid_id == "JX_SHSY":
                if int(code) == 0:
                    task_status = TaskStatusValue.INFO_COMPLETED
                    TaskCDNLOCK.delete_lock(cor_id)
                else:
                    task_status = TaskStatusValue.INFO_FAILED

                TaskModel.objects.filter(pk=cor_id).update(status=task_status)

                xml = wl_response.format(desc, code)
                logging.warning("callback_wl_response_xml:{}".format(xml))
                return xml

            elif cspid_id in [self.csp_id_hw, self.csp_id_zx]:
                # 都是 cdn回执 保证两个cdn都成功了
                if int(code) == 0:
                    if TaskCDNLOCK.add_lock(cor_id, cspid_id):  # 表示之前没有有成功的回执了
                        task_status = TaskStatusValue.FILE_TRANSFERING
                        remark = cspid_id
                    else:
                        last_cspid = TaskCDNLOCK.get_value(cor_id).decode()
                        logging.warning("cdn回执，两个cdn都成功 last_cspid:{} cspid_id:{}".format(last_cspid, cspid_id))
                        if last_cspid != cspid_id:
                            task_status = TaskStatusValue.INFO_PENDING
                            remark = self.csp_id_hw + "+" + self.csp_id_zx
                        else:
                            task_status = TaskStatusValue.FILE_TRANSFERING
                            remark = "{} repeat".format(cspid_id)
                else:
                    task_status = TaskStatusValue.FILE_FAILED
                    remark = "{} fail".format(cspid_id)
                task = TaskModel.objects.filter(pk=cor_id).first()
                TaskModel.objects.filter(pk=cor_id).update(status=task_status, remark=remark)
                TaskQueue.update(task.level, cor_id, task_status)

        except Exception as e:
            code, desc = -1, "未携带xml报文体,xml解析失败."
            print(e)
            logging.warning("callback_Exception:{}".format(e))
        xml = re_response_xml.format(desc, code)
        logging.warning("callback_response_xml:{}".format(xml))
        return xml
