# -*- coding: utf-8 -*-
"""
issue_certificate_model.py
"""
from __future__ import print_function, unicode_literals, absolute_import, division

import json
from datetime import datetime

from peewee import CharField, IntegerField, DateTimeField, AutoField, TextField, BooleanField
from playhouse.shortcuts import model_to_dict

from domain_admin.enums.challenge_deploy_type_enum import ChallengeDeployTypeEnum
from domain_admin.enums.deploy_status_enum import DeployStatusEnum
from domain_admin.enums.ssl_deploy_type_enum import SSLDeployTypeEnum
from domain_admin.enums.valid_status_enum import ValidStatus
from domain_admin.model.base_model import BaseModel
from domain_admin.utils import datetime_util
from domain_admin.utils.acme_util.challenge_type import ChallengeType
from domain_admin.utils.acme_util.directory_type_enum import DirectoryTypeEnum
from domain_admin.utils.acme_util.key_type_enum import KeyTypeEnum

# 常量
URI_ROOT_PATH = ".well-known/acme-challenge"


class IssueCertificateModel(BaseModel):
    """
    申请证书
    步骤：
      1、验证域名 http(ssh) dns(dns-api)
      2、签发证书
      3、部署证书 ssh api

    @since v1.5.6
    """
    id = AutoField(primary_key=True)

    # 用户id
    user_id = IntegerField(default=0)

    # 域名列表
    domain_raw = TextField(default='')

    # SSL证书
    ssl_certificate = TextField(default=None, null=True)

    # SSL证书私钥
    ssl_certificate_key = TextField(default=None, null=True)

    # SSL签发时间
    start_time = DateTimeField(default=None, null=True)

    # SSL过期时间
    expire_time = DateTimeField(default=None, null=True)

    # 证书提供商 @since v1.6.35
    directory_type = CharField(default=DirectoryTypeEnum.LETS_ENCRYPT, null=True)

    # 加密方式 @since v1.6.35
    key_type = CharField(default=KeyTypeEnum.RSA, null=True)

    # 域名验证类型 http dns
    challenge_type = CharField(default=ChallengeType.HTTP01, null=True)

    # 验证文件部署方式 ssh dns
    challenge_deploy_type_id = IntegerField(default=ChallengeDeployTypeEnum.SSH)

    # 验证文件部署账号
    challenge_deploy_id = IntegerField(default=0)

    # 验证文件部署状态
    challenge_deploy_status = IntegerField(default=DeployStatusEnum.PENDING)

    # 验证文件部署目录
    deploy_verify_path = CharField(default=None, null=True)

    # 域名验证token
    # @Deprecation @since v1.5.9
    token = CharField(default=None, null=True)

    # 域名验证数据
    # @Deprecation @since v1.5.9
    validation = CharField(default=None, null=True)

    # 验证状态url
    # @Deprecation @since v1.5.9
    status_url = CharField(default=None, null=True)

    # 验证状态 valid pending
    status = CharField(default=ValidStatus.PENDING, null=True)

    # 部署方式 @since 1.6.33 可选：ssh api
    # @since 1.6.43 新增 oss
    deploy_type_id = IntegerField(default=SSLDeployTypeEnum.SSH)

    # 部署机器
    # @since 1.6.33 部署机器
    deploy_host_id = IntegerField(default=0)

    # key部署路径
    deploy_key_file = CharField(default=None, null=True)

    # pem部署路径
    deploy_fullchain_file = CharField(default=None, null=True)

    # 部署重启命令
    deploy_reloadcmd = CharField(default=None, null=True)

    # 部署请求url
    deploy_url = CharField(default=None, null=True)

    # 部署请求头
    deploy_header_raw = TextField(default=None, null=True)

    # 部署参数
    # @since 1.6.43
    deploy_params_raw = TextField(default=None, null=True)

    # ssl证书文件部署状态
    ssl_deploy_status = IntegerField(default=DeployStatusEnum.PENDING)

    # 自动续期
    is_auto_renew = BooleanField(default=False)

    # 续期执行状态 0：成功，1：失败
    # @since v1.6.74
    renew_status = IntegerField(default=0)

    # 续期失败信息
    # @since v1.6.74
    renew_message = TextField(default=None, null=True)

    # 数据版本号
    version = IntegerField(default=0, null=False)

    # 创建时间
    create_time = DateTimeField(default=datetime.now)

    # 更新时间
    update_time = DateTimeField(default=datetime.now)

    class Meta:

        table_name = 'tb_issue_certificate'

    @property
    def create_time_label(self):
        return datetime_util.time_for_human(self.create_time)

    @property
    def update_time_label(self):
        return datetime_util.time_for_human(self.update_time)

    @property
    def start_date(self):
        if self.start_time and isinstance(self.start_time, datetime):
            return self.start_time.strftime('%Y-%m-%d')

    @property
    def expire_date(self):
        if self.expire_time and isinstance(self.expire_time, datetime):
            return self.expire_time.strftime('%Y-%m-%d')

    @property
    def challenge_url(self):
        return '/.well-known/acme-challenge/{}'.format(self.token)

    @property
    def has_ssl_certificate(self):
        """
        是否有证书文件
        :return:
        """
        return True if self.ssl_certificate else False

    @property
    def domains(self):
        if self.domain_raw:
            return json.loads(self.domain_raw)
        else:
            return []

    @property
    def domain_validation_urls(self):
        return []

        # ["http://" + domain + '/' + URI_ROOT_PATH + '/' + self.token
        # for domain in self.domains]

    @property
    def deploy_header(self):
        if self.deploy_header_raw:
            return json.loads(self.deploy_header_raw)
        else:
            return {}

    @property
    def can_auto_renew(self):
        """
        能够选择自动续期
        :return:
        """
        return self.ssl_deploy_status == DeployStatusEnum.SUCCESS \
               and self.challenge_deploy_status == DeployStatusEnum.SUCCESS

    def to_dict(self):
        return model_to_dict(
            self,
            extra_attrs=[
                'domains',
                'create_time_label',
                'update_time_label',
                'can_auto_renew',
                'domain_validation_urls'
            ]
        )

    @property
    def deploy_params(self):
        if self.deploy_params_raw:
            return json.loads(self.deploy_params_raw)
        else:
            return {}
