# -*- coding:utf-8 -*-
"""
人员当日jira任务、故事状态流转
"""
import os, sys

file_dir = os.path.dirname(__file__)
project_dir = os.path.abspath(os.path.join(file_dir, "..", "..", ".."))
sys.path.append(project_dir)

from jira import JIRA
from base_framework.public_tools.utils import Tools
from base_framework.public_tools.read_config import ReadConfig
from base_framework.platform_tools.Message_service.Feishu_api import FeiShuMessage,get_user_name_by_email_prefix,get_feishu_config_value
from configparser import ConfigParser
from base_framework.base_config.current_pth import *
import datetime

tools = Tools()
ReadConfig = ReadConfig(filename=la_config_path)
FS_INFO = [{"team": "TO", "users": "wuyonggang,xuwenjun,luohong"},
           {"team": "TO-RD", "users": "fengtian,guosongchao,zhaoxiaofang,"
                                      "zhuliang,majincheng,gaozhijun,liuxuegang,"
                                      "zhangxiong"},
           {"team": "USER-FE", "users": "zhaofei,liuxinlin,qingchen,yefei,xiangming,jianghao,jianglingmin,xuchangle,"
                                        "libaicheng,gouyuheng,jixiang.dong,baiyang01"}
           ]


class JiraApi:
    def __init__(self):
        self.jira = JIRA(server='https://jira.bg.huohua.cn/',
                         basic_auth=("wuyonggang", "Mima@123"))

    def close_jira_subtask(self, user_name):
        """
        功能: 关闭指定人员名下当天结束的子任务
        请求参数 user_name （指定人员jira登录名，type: list）
        """
        bad_name = []
        right_name = []
        for j in user_name:
            if j not in ReadConfig.get_sections():
                bad_name.append(j)
            elif j in ReadConfig.get_sections():
                right_name.append(j)
        success = []
        false = []
        today_time = tools.get_format_date(r_type=1)
        work_start_time = datetime.datetime.strptime('{0} 10:00:00'.format(today_time), '%Y-%m-%d %H:%M:%S')
        for name in right_name:
            jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
            jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计,' \
                  ' 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 处理中, 关闭) AND resolution = Unresolved' \
                  ' AND (QA in ({0})  OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
            issues = jira.search_issues(jql, fields='')
            # if len(issues) == 0: break
            not_need_closed = 0
            for i in issues:
                s = list(jira.transitions(i))
                close_status_id = [x['id'] for x in s if x['name'] == '关闭']
                if str(i.fields.status) == '处理中':
                    if i.fields.aggregatetimeestimate != None:
                        if i.fields.aggregatetimeestimate > 28800:
                            jira.add_worklog(i, timeSpent='7', started=work_start_time)
                        elif 0 < i.fields.aggregatetimeestimate <= 28800:
                            jira.add_worklog(i, timeSpent='{0}'.format(i.fields.aggregatetimeestimate / 3600),
                                             started=work_start_time)
                    else:
                        jira.add_worklog(i, timeSpent='8', started=work_start_time)
                if str(i.fields.status) == '处理中' and str(i.fields.customfield_13406) == today_time:
                    jira.transition_issue(i, int(close_status_id[0]))
                else:
                    not_need_closed += 1
            issues2 = jira.search_issues(jql, fields='')
            if not_need_closed == len(issues2):
                success.append(name)
            else:
                false.append(name)
        return "{0}今日结束的子任务已关闭成功； {1}今日结束的子任务关闭失败; {2}没有进行账号配置".format(success, false, bad_name)

    def start_jira_subtask(self, user_name):
        """
        功能: 将待开始为今天的子任务状态流转为“处理中”
        请求参数 user_name （指定人员jira登录名，type: list）
        """
        bad_name = []
        right_name = []
        for j in user_name:
            if j not in ReadConfig.get_sections():
                bad_name.append(j)
            elif j in ReadConfig.get_sections():
                right_name.append(j)
        success = []
        false = []
        for name in right_name:
            jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
            jql = 'project = HHC AND issuetype = 子任务 AND status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, ' \
                  '排期, 执行, 开发, 待测试, QA测试, SIM验证, 验证中, 待办, 关闭) AND resolution = Unresolved' \
                  ' AND (QA in ({0})  OR assignee in ({1})) ORDER BY priority DESC, updated DESC'.format(name,name)
            today_time = tools.get_format_date(r_type=1)
            issues = jira.search_issues(jql, fields='')
            # if len(issues) == 0: break
            not_need_update = 0
            for i in issues:
                s = list(jira.transitions(i))
                start_status_id = [x['id'] for x in s if x['name'] == '处理中']
                if str(i.fields.status) == '待办' and str(i.fields.customfield_12700) == today_time:
                    jira.transition_issue(i, int(start_status_id[0]))
                else:
                    not_need_update += 1
            issues2 = jira.search_issues(jql, fields='')
            if not_need_update == len(issues2):
                success.append(name)
            else:
                false.append(name)
        return "{0}今日开始的子任务已将状态修改为“处理中”‘； {1}今日开始的子任务状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)

    def change_story(self, user_name, type):
        """
        功能: 将提测时间为今天的指定人员名下的故事状态修改至“QA测试”
        请求参数 user_name （指定人员jira登录名，type: list）
               type   (故事需要修改至的状态  1：提测日为今天，状态修改至【QA测试】   2：上线日为今天，状态修改至【关闭】)
        """
        bad_name = []
        right_name = []
        for j in user_name:
            if j not in ReadConfig.get_sections():
                bad_name.append(j)
            elif j in ReadConfig.get_sections():
                right_name.append(j)
        success = []
        false = []
        for name in right_name:
            jira = JIRA(server='https://jira.bg.huohua.cn/', basic_auth=(name, ReadConfig.get_value(name, 'password')))
            jql = "project = HHC AND issuetype = 故事 AND " \
                  "status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, QA测试, SIM验证, 处理中, 关闭)" \
                  " AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
            today_time = tools.get_format_date(r_type=1)
            issues = jira.search_issues(jql, fields='')
            # if len(issues) == 0 : break
            x = 0
            need_update = 0
            if type == 1:  # 将故事状态一直流转至“QA测试”
                for i in issues:
                    if str(i.fields.status) == 'QA测试' or str(i.fields.status) == 'SIM验证': need_update += 1
                    if str(i.fields.customfield_10504) == today_time:
                        if str(i.fields.status) != 'QA测试' and str(i.fields.status) != 'SIM验证':
                            need_update += 1
                            for j in range(8):
                                jira.transition_issue(i, int(jira.transitions(i)[2]['id']))
                                issues_2 = jira.search_issues(jql, fields='')  # 重新获取所有故事
                                status_now = issues_2[x].fields.status
                                print(status_now)
                                if str(status_now) == 'QA测试' or str(status_now) == 'SIM验证':
                                    break
                    x += 1
                jql2 = "project = HHC AND issuetype = 故事 AND " \
                       "status in (重新打开, 启动, 需求池, 暂停, 计划, 产品需求设计, 产品需求内审, 需求评审, 排期, 执行, 开发, 待测试, 验证中, 待办, 处理中, 关闭)" \
                       " AND resolution = Unresolved AND QA in ({0}) ORDER BY priority DESC, updated DESC".format(name)
                issues2 = jira.search_issues(jql2, fields='')
                if len(issues2) == len(issues) - need_update:
                    success.append(name)
                else:
                    false.append(name)
            elif type == 2:  # 直接将故事关闭
                for i in issues:
                    if str(i.fields.customfield_10606) == today_time:
                        jira.transition_issue(i, int(jira.transitions(i)[1]['id']), comment="已上线")  # 将故事修改为关闭状态
                        need_update += 1
                issues2 = jira.search_issues(jql, fields='')
                if len(issues2) + need_update == len(issues):
                    success.append(name)
                else:
                    false.append(name)

        return "{0}今日的故事已将状态修改成功！； {1}今日的故事状态修改失败; {2}没有进行账号配置".format(success, false, bad_name)

    def change_jira_status(self, user_name):
        """
        功能: 判断当前时间是否在下午18:00点以前，来选择打开或关闭【子任务】和【故事】
        请求参数 user_name （指定人员jira登录名，type: list）
        """
        time_now = tools.get_format_date(r_type=4)
        time_now2 = '{0} 18:00:00'.format(time_now[0:10:1])
        if time_now < '{0} 18:00:00'.format(time_now2):
            a = self.start_jira_subtask(user_name)
            b = self.change_story(user_name, type=1)
            return a + '\n' + b
        elif time_now >= '{0} 18:00:00'.format(time_now2):
            a = self.close_jira_subtask(user_name)
            b = self.change_story(user_name, type=2)
            return a + '\n' + b

    def query_jira_subtask(self, user_name, begin_date=0, end_date=0):
        """
        | 功能 | 查询用户对应的jira子任务 |
        | 入参 | user_name  | 用户名字 |
        |     | begin_date | 开始时间：0-今天，X-未来X天，-X-过去的X天 |
        |     | end_date   | 开始时间：0-今天，X-未来X天，-X-过去的X天 |
        """
        b_date = tools.get_format_date(r_type=1, add_days=int(begin_date))
        e_date = tools.get_format_date(r_type=1, add_days=int(end_date))
        jql = "issuetype = 子任务 AND 计划开始时间 <= {} AND 计划结束时间 >= {} AND assignee in ({}) ORDER BY cf[12700] ASC"\
            .format(b_date, e_date, user_name)
        issues = self.jira.search_issues(jql, fields='')
        # print(jql)
        return issues
        # for item in issues:
        #     print("{0}:{1}, 当前状态:{2}".format(item.key, item.fields.summary, item.fields.status))

    def query_jira_by_id(self, jira_id):
        """
        | 功能 | 跟进jira的id查询具体详情 |
        | 入参 | jira_id  | jira的id |
        """
        jql = "id={}".format(jira_id)
        issues = self.jira.search_issues(jql, fields='')
        if len(issues) == 0:
            raise Exception("根据jira_id未查询到对应的jira信息，请检查....")
        rd = issues[0].fields.assignee.displayName
        qa = issues[0].fields.reporter.displayName
        title = issues[0].fields.summary
        status = issues[0].fields.status
        j_time = issues[0].fields.created
        j_time = j_time[0:10] + ' ' + j_time[11:19]
        return {"jira_rd": rd,
                "jira_qa": qa,
                "jira_title": title,
                "jira_time": j_time,
                "jira_status": str(status)}

    def query_overdue_issues(self, user_name):
        """
        | 功能 | 查询逾期的子任务和故事 |
        | 入参 | 无  |
        """
        today = tools.get_format_date()
        check_time = tools.get_format_date(r_type=4)
        if check_time < "{} 17:00:00".format(today):
            jql = "issuetype in (故事,子任务) AND (计划结束时间<now() OR 计划上线时间<now()) AND status!=关闭 AND " \
                  "(assignee={0} OR QA={0})".format(user_name)
        else:
            jql = "issuetype in (故事,子任务) AND (计划结束时间<=now() OR 计划上线时间<=now()) AND status!=关闭 AND " \
                  "(assignee={0} OR QA={0})".format(user_name)
        issues = self.jira.search_issues(jql, fields='')
        return issues

    def check_overdue_issues(self):
        """检查预期未关闭的故事和子任务"""
        today = tools.get_format_date()
        fs = FS_INFO[0]
        user_list = fs['users'].split(',')
        remind_info = []
        for user in user_list:
            issues = self.query_overdue_issues(user_name=user)
            if issues:
                for issue in issues:
                    issue_info = [user, issue.key]
                    remind_info.append(issue_info)
        if remind_info:
            msg = "【JIRA任务延期提醒{}】：\n".format(today)
            for info in remind_info:
                user_name = get_user_name_by_email_prefix(email_prefix=info[0])
                open_id = get_feishu_config_value(option_key=user_name)
                at_msg = "  |--<at user_id='{}'>{}</at>".format(open_id, user_name)
                msg = msg + at_msg + ": https://jira.bg.huohua.cn/browse/{}\n".format(info[1])
            msg = msg + "  |--请及时关闭以上逾期任务..."
            print(msg)
            fs = FeiShuMessage(team=fs['team'])
            fs.send_text(msg=msg)
        else:
            print("++++++++++++++++++++++")
            print("| 所有任务或故事均已关闭 |")
            print("++++++++++++++++++++++")

    def check_pdp_standard(self):
        """查找当天有无子任务，没有则发送飞书消息提醒"""
        # 非工作日构建
        today = tools.get_format_date()
        if not tools.check_the_date_is_a_working_day(today):
            print("### 非工作日，不检查....")
            return False

        for fs in FS_INFO:
            user_list = fs['users'].split(',')
            need_remind_user = []
            for user in user_list:
                issues = self.query_jira_subtask(user_name=user)
                if not issues:
                    need_remind_user.append(user)
            if need_remind_user:
                msg = "【JIRA子任务提醒{}】：\n  |--".format(today)
                for user in need_remind_user:
                    user_name = get_user_name_by_email_prefix(email_prefix=user)
                    open_id = get_feishu_config_value(option_key=user_name)
                    at_msg = "<at user_id='{}'>{}</at>".format(open_id, user_name)
                    msg = msg + at_msg
                msg = msg + "\n  |--请及时添加与今日工作对应的子任务哦..."
                print(msg)
                fs = FeiShuMessage(team=fs['team'])
                fs.send_text(msg=msg)
            else:
                print("++++++++++++++++++++++++++++++++")
                print("| {} 满足pdp规范，无须提示 |".format(fs['team']))
                print("++++++++++++++++++++++++++++++++")


if __name__ == '__main__':

    # 关闭自动修改jira的代码，不要再打开了...
    # lp = Jira_About()
    # print(lp.change_jira_status(['liupeng', 'zhourenhua', 'xuwenjun', 'lichao04', 'wanggang02', 'baoli']))

    # 以下内容若有修改，请勿上传，否则会影响jira监控的每日构建
    # 1.获取命令行参数
    cmd_params = sys.argv
    try:
        index = cmd_params.index('-t')
    except ValueError:
        raise Exception("类型参数必填：pdp-检查PDP规范，overdue-检查预期未关闭的故事和子任务....")
    else:
        check_type = cmd_params[index + 1]
        if check_type.lower() not in ("pdp", "overdue"):
            raise Exception("目前仅支持pdp和overdue，但你输入的是：{}".format(check_type))

    jira = JiraApi()
    if check_type.lower() == "pdp":
        jira.check_pdp_standard()
    elif check_type.lower() == "overdue":
        jira.check_overdue_issues()
