#coding: utf-8

# Copyright Daniel Roesler, under MIT license, see LICENSE at github.com/diafygi/acme-tiny
import argparse, subprocess, json, os, sys, base64, binascii, time, hashlib, re, copy, textwrap
from OpenSSL import crypto
import requests,platform

class acme:
    DEFAULT_CA = "https://acme-v02.api.letsencrypt.org" # DEPRECATED! USE DEFAULT_DIRECTORY_URL INSTEAD
    DEFAULT_DIRECTORY_URL = "https://acme-v02.api.letsencrypt.org/directory"

    def __init__(self,domain_name, domain_alt_names = None, contact_email = None, account_key=None, certificate_key=None, bits=2048, digest="sha256",ACME_REQUEST_TIMEOUT = 10, ACME_DIRECTORY_URL='https://acme-v02.api.letsencrypt.org/directory'):
        self.bits = bits
        self.digest = digest

        self.domain_name = domain_name
        self.contact_email = contact_email
        self.ACME_DIRECTORY_URL = ACME_DIRECTORY_URL
        self.ACME_REQUEST_TIMEOUT = ACME_REQUEST_TIMEOUT

        if not domain_alt_names:
            domain_alt_names = []
        self.domain_alt_names = domain_alt_names

        if not account_key:
            self.account_key = self.create_account_key()
            self.PRIOR_REGISTERED = False
        else:
            self.account_key = account_key
            self.PRIOR_REGISTERED = True

        #try:
        self.all_domain_names = copy.copy(self.domain_alt_names)
        self.all_domain_names.insert(0, self.domain_name)
        self.domain_alt_names = list(set(self.domain_alt_names))

        self.User_Agent = self.get_user_agent()
        print(self.User_Agent)
        acme_endpoints = self.get_acme_endpoints().json()
        self.ACME_GET_NONCE_URL = acme_endpoints["newNonce"]
        self.ACME_TOS_URL = acme_endpoints["meta"]["termsOfService"]
        self.ACME_KEY_CHANGE_URL = acme_endpoints["keyChange"]
        self.ACME_NEW_ACCOUNT_URL = acme_endpoints["newAccount"]
        self.ACME_NEW_ORDER_URL = acme_endpoints["newOrder"]
        self.ACME_REVOKE_CERT_URL = acme_endpoints["revokeCert"]
        #except :
        #    pass

    @staticmethod
    def get_user_agent():
        return "python-requests/{requests_version} ({system}: {machine}) btpanel windows)".format(requests_version = requests.__version__, system = platform.system(), machine = platform.machine())

    def get_acme_endpoints(self):
        headers = {"User-Agent": self.User_Agent}
        get_acme_endpoints = requests.get(self.ACME_DIRECTORY_URL, timeout = self.ACME_REQUEST_TIMEOUT, headers=headers)
        if get_acme_endpoints.status_code not in [200, 201]:
            raise ValueError("Error while getting Acme endpoints: status_code={status_code}".format(status_code=get_acme_endpoints.status_code))
        return get_acme_endpoints

    def create_certificate_key(self):
        return self.create_key().decode()

    def create_account_key(self):
        return self.create_key().decode()

    def create_key(self, key_type = crypto.TYPE_RSA):
        key = crypto.PKey()
        key.generate_key(key_type, self.bits)
        private_key = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)
        return private_key

    def create_csr(self):
        """
        https://tools.ietf.org/html/draft-ietf-acme-acme#section-7.4
        The CSR is sent in the base64url-encoded version of the DER format. (NB: this
        field uses base64url, and does not include headers, it is different from PEM.)
        """
        self.logger.debug("create_csr")
        X509Req = crypto.X509Req()
        X509Req.get_subject().CN = self.domain_name

        if self.domain_alt_names:
            SAN = "DNS:{0}, ".format(self.domain_name).encode("utf8") + ", ".join(
                "DNS:" + i for i in self.domain_alt_names
            ).encode("utf8")
        else:
            SAN = "DNS:{0}".format(self.domain_name).encode("utf8")

        X509Req.add_extensions(
            [
                crypto.X509Extension(
                    "subjectAltName".encode("utf8"), critical=False, value=SAN
                )
            ]
        )
        pk = crypto.load_privatekey(
            crypto.FILETYPE_PEM, self.certificate_key.encode()
        )
        X509Req.set_pubkey(pk)
        X509Req.set_version(2)
        X509Req.sign(pk, self.digest)
        return crypto.dump_certificate_request(crypto.FILETYPE_ASN1, X509Req)

    #获取证书
    def get_crt(self,data):
        ret = self.create_certificate_key()
        print(ret)

if __name__ == "__main__":
    data = {}
    data['siteName'] = "ffce.cn"
    data['domains'] = ['d40.ffce.cn']

    let = acme(data['siteName'],data['domains'])
    result = let.get_crt(data)
    print(result)
