# SPDX-License-Identifier: BSD-3-Clause
#
# Copyright 2023 Raritan Inc. All rights reserved.
#
# This is an auto-generated file.

#
# Section generated by IdlC from "ServerSSLCert.idl"
#

import raritan.rpc
from raritan.rpc import Interface, Structure, ValueObject, Enumeration, typecheck, DecodeException
import raritan.rpc.cert


# interface
class ServerSSLCert(Interface):
    idlType = "cert.ServerSSLCert:3.0.0"

    SUCCESS = 0

    ERR_GEN_KEY_LEN_INVALID = 100

    ERR_GEN_CSR_OR_CERT_PENDING = 101

    ERR_GEN_KEY_GEN_FAILED = 102

    ERR_GEN_KEY_TYPE_INVALID = 103

    ERR_GEN_ELLIPTIC_CURVE_INVALID = 104

    ERR_INSTALL_KEY_MISSING = 200

    ERR_INSTALL_CERT_MISSING = 201

    ERR_INSTALL_CERT_FORMAT_INVALID = 202

    ERR_INSTALL_CERT_KEY_MISMATCH = 203

    ERR_INSTALL_KEY_FORMAT_INVALID = 204

    # structure
    class CommonAttributes(Structure):
        idlType = "cert.ServerSSLCert_3_0_0.CommonAttributes:1.0.0"
        elements = ["country", "stateOrProvince", "locality", "organization", "organizationalUnit", "commonName", "emailAddress"]

        def __init__(self, country="", stateOrProvince="", locality="", organization="", organizationalUnit="", commonName="", emailAddress=""):
            typecheck.is_string(country, AssertionError)
            typecheck.is_string(stateOrProvince, AssertionError)
            typecheck.is_string(locality, AssertionError)
            typecheck.is_string(organization, AssertionError)
            typecheck.is_string(organizationalUnit, AssertionError)
            typecheck.is_string(commonName, AssertionError)
            typecheck.is_string(emailAddress, AssertionError)

            self.country = country
            self.stateOrProvince = stateOrProvince
            self.locality = locality
            self.organization = organization
            self.organizationalUnit = organizationalUnit
            self.commonName = commonName
            self.emailAddress = emailAddress

        @classmethod
        def decode(cls, json, agent):
            obj = cls(
                country = json['country'],
                stateOrProvince = json['stateOrProvince'],
                locality = json['locality'],
                organization = json['organization'],
                organizationalUnit = json['organizationalUnit'],
                commonName = json['commonName'],
                emailAddress = json['emailAddress'],
            )
            return obj

        def encode(self):
            json = {}
            json['country'] = self.country
            json['stateOrProvince'] = self.stateOrProvince
            json['locality'] = self.locality
            json['organization'] = self.organization
            json['organizationalUnit'] = self.organizationalUnit
            json['commonName'] = self.commonName
            json['emailAddress'] = self.emailAddress
            return json

    # enumeration
    class KeyType(Enumeration):
        idlType = "cert.ServerSSLCert_3_0_0.KeyType:1.0.0"
        values = ["KEY_TYPE_UNKNOWN", "KEY_TYPE_RSA", "KEY_TYPE_ECDSA"]

    KeyType.KEY_TYPE_UNKNOWN = KeyType(0)
    KeyType.KEY_TYPE_RSA = KeyType(1)
    KeyType.KEY_TYPE_ECDSA = KeyType(2)

    # enumeration
    class EllipticCurve(Enumeration):
        idlType = "cert.ServerSSLCert_3_0_0.EllipticCurve:1.0.0"
        values = ["EC_CURVE_UNKNOWN", "EC_CURVE_NIST_P256", "EC_CURVE_NIST_P384", "EC_CURVE_NIST_P521"]

    EllipticCurve.EC_CURVE_UNKNOWN = EllipticCurve(0)
    EllipticCurve.EC_CURVE_NIST_P256 = EllipticCurve(1)
    EllipticCurve.EC_CURVE_NIST_P384 = EllipticCurve(2)
    EllipticCurve.EC_CURVE_NIST_P521 = EllipticCurve(3)

    # structure
    class ReqInfo(Structure):
        idlType = "cert.ServerSSLCert_3_0_0.ReqInfo:1.0.0"
        elements = ["subject", "names", "keyType", "ellipticCurve", "rsaKeyLength"]

        def __init__(self, subject=None, names=[], keyType=None, ellipticCurve=None, rsaKeyLength=0):
            if subject is None:
                subject = raritan.rpc.cert.ServerSSLCert.CommonAttributes()
            if keyType is None:
                keyType = raritan.rpc.cert.ServerSSLCert.KeyType.KEY_TYPE_UNKNOWN
            if ellipticCurve is None:
                ellipticCurve = raritan.rpc.cert.ServerSSLCert.EllipticCurve.EC_CURVE_UNKNOWN
            typecheck.is_struct(subject, raritan.rpc.cert.ServerSSLCert.CommonAttributes, AssertionError)
            for x0 in names:
                typecheck.is_string(x0, AssertionError)
            typecheck.is_enum(keyType, raritan.rpc.cert.ServerSSLCert.KeyType, AssertionError)
            typecheck.is_enum(ellipticCurve, raritan.rpc.cert.ServerSSLCert.EllipticCurve, AssertionError)
            typecheck.is_int(rsaKeyLength, AssertionError)

            self.subject = subject
            self.names = names
            self.keyType = keyType
            self.ellipticCurve = ellipticCurve
            self.rsaKeyLength = rsaKeyLength

        @classmethod
        def decode(cls, json, agent):
            obj = cls(
                subject = raritan.rpc.cert.ServerSSLCert.CommonAttributes.decode(json['subject'], agent),
                names = [x0 for x0 in json['names']],
                keyType = raritan.rpc.cert.ServerSSLCert.KeyType.decode(json['keyType']),
                ellipticCurve = raritan.rpc.cert.ServerSSLCert.EllipticCurve.decode(json['ellipticCurve']),
                rsaKeyLength = json['rsaKeyLength'],
            )
            return obj

        def encode(self):
            json = {}
            json['subject'] = raritan.rpc.cert.ServerSSLCert.CommonAttributes.encode(self.subject)
            json['names'] = [x0 for x0 in self.names]
            json['keyType'] = raritan.rpc.cert.ServerSSLCert.KeyType.encode(self.keyType)
            json['ellipticCurve'] = raritan.rpc.cert.ServerSSLCert.EllipticCurve.encode(self.ellipticCurve)
            json['rsaKeyLength'] = self.rsaKeyLength
            return json

    # structure
    class CertInfo(Structure):
        idlType = "cert.ServerSSLCert_3_0_0.CertInfo:1.0.0"
        elements = ["subject", "issuer", "names", "invalidBefore", "invalidAfter", "serialNumber", "keyType", "ellipticCurve", "rsaKeyLength"]

        def __init__(self, subject=None, issuer=None, names=[], invalidBefore="", invalidAfter="", serialNumber="", keyType=None, ellipticCurve=None, rsaKeyLength=0):
            if subject is None:
                subject = raritan.rpc.cert.ServerSSLCert.CommonAttributes()
            if issuer is None:
                issuer = raritan.rpc.cert.ServerSSLCert.CommonAttributes()
            if keyType is None:
                keyType = raritan.rpc.cert.ServerSSLCert.KeyType.KEY_TYPE_UNKNOWN
            if ellipticCurve is None:
                ellipticCurve = raritan.rpc.cert.ServerSSLCert.EllipticCurve.EC_CURVE_UNKNOWN
            typecheck.is_struct(subject, raritan.rpc.cert.ServerSSLCert.CommonAttributes, AssertionError)
            typecheck.is_struct(issuer, raritan.rpc.cert.ServerSSLCert.CommonAttributes, AssertionError)
            for x0 in names:
                typecheck.is_string(x0, AssertionError)
            typecheck.is_string(invalidBefore, AssertionError)
            typecheck.is_string(invalidAfter, AssertionError)
            typecheck.is_string(serialNumber, AssertionError)
            typecheck.is_enum(keyType, raritan.rpc.cert.ServerSSLCert.KeyType, AssertionError)
            typecheck.is_enum(ellipticCurve, raritan.rpc.cert.ServerSSLCert.EllipticCurve, AssertionError)
            typecheck.is_int(rsaKeyLength, AssertionError)

            self.subject = subject
            self.issuer = issuer
            self.names = names
            self.invalidBefore = invalidBefore
            self.invalidAfter = invalidAfter
            self.serialNumber = serialNumber
            self.keyType = keyType
            self.ellipticCurve = ellipticCurve
            self.rsaKeyLength = rsaKeyLength

        @classmethod
        def decode(cls, json, agent):
            obj = cls(
                subject = raritan.rpc.cert.ServerSSLCert.CommonAttributes.decode(json['subject'], agent),
                issuer = raritan.rpc.cert.ServerSSLCert.CommonAttributes.decode(json['issuer'], agent),
                names = [x0 for x0 in json['names']],
                invalidBefore = json['invalidBefore'],
                invalidAfter = json['invalidAfter'],
                serialNumber = json['serialNumber'],
                keyType = raritan.rpc.cert.ServerSSLCert.KeyType.decode(json['keyType']),
                ellipticCurve = raritan.rpc.cert.ServerSSLCert.EllipticCurve.decode(json['ellipticCurve']),
                rsaKeyLength = json['rsaKeyLength'],
            )
            return obj

        def encode(self):
            json = {}
            json['subject'] = raritan.rpc.cert.ServerSSLCert.CommonAttributes.encode(self.subject)
            json['issuer'] = raritan.rpc.cert.ServerSSLCert.CommonAttributes.encode(self.issuer)
            json['names'] = [x0 for x0 in self.names]
            json['invalidBefore'] = self.invalidBefore
            json['invalidAfter'] = self.invalidAfter
            json['serialNumber'] = self.serialNumber
            json['keyType'] = raritan.rpc.cert.ServerSSLCert.KeyType.encode(self.keyType)
            json['ellipticCurve'] = raritan.rpc.cert.ServerSSLCert.EllipticCurve.encode(self.ellipticCurve)
            json['rsaKeyLength'] = self.rsaKeyLength
            return json

    # structure
    class Info(Structure):
        idlType = "cert.ServerSSLCert_3_0_0.Info:1.0.0"
        elements = ["havePendingReq", "havePendingCert", "pendingReqInfo", "pendingCertInfo", "pendingCertChainInfos", "activeCertInfo", "activeCertChainInfos", "maxSignDays"]

        def __init__(self, havePendingReq=False, havePendingCert=False, pendingReqInfo=None, pendingCertInfo=None, pendingCertChainInfos=[], activeCertInfo=None, activeCertChainInfos=[], maxSignDays=0):
            if pendingReqInfo is None:
                pendingReqInfo = raritan.rpc.cert.ServerSSLCert.ReqInfo()
            if pendingCertInfo is None:
                pendingCertInfo = raritan.rpc.cert.ServerSSLCert.CertInfo()
            if activeCertInfo is None:
                activeCertInfo = raritan.rpc.cert.ServerSSLCert.CertInfo()
            typecheck.is_bool(havePendingReq, AssertionError)
            typecheck.is_bool(havePendingCert, AssertionError)
            typecheck.is_struct(pendingReqInfo, raritan.rpc.cert.ServerSSLCert.ReqInfo, AssertionError)
            typecheck.is_struct(pendingCertInfo, raritan.rpc.cert.ServerSSLCert.CertInfo, AssertionError)
            for x0 in pendingCertChainInfos:
                typecheck.is_struct(x0, raritan.rpc.cert.ServerSSLCert.CertInfo, AssertionError)
            typecheck.is_struct(activeCertInfo, raritan.rpc.cert.ServerSSLCert.CertInfo, AssertionError)
            for x0 in activeCertChainInfos:
                typecheck.is_struct(x0, raritan.rpc.cert.ServerSSLCert.CertInfo, AssertionError)
            typecheck.is_int(maxSignDays, AssertionError)

            self.havePendingReq = havePendingReq
            self.havePendingCert = havePendingCert
            self.pendingReqInfo = pendingReqInfo
            self.pendingCertInfo = pendingCertInfo
            self.pendingCertChainInfos = pendingCertChainInfos
            self.activeCertInfo = activeCertInfo
            self.activeCertChainInfos = activeCertChainInfos
            self.maxSignDays = maxSignDays

        @classmethod
        def decode(cls, json, agent):
            obj = cls(
                havePendingReq = json['havePendingReq'],
                havePendingCert = json['havePendingCert'],
                pendingReqInfo = raritan.rpc.cert.ServerSSLCert.ReqInfo.decode(json['pendingReqInfo'], agent),
                pendingCertInfo = raritan.rpc.cert.ServerSSLCert.CertInfo.decode(json['pendingCertInfo'], agent),
                pendingCertChainInfos = [raritan.rpc.cert.ServerSSLCert.CertInfo.decode(x0, agent) for x0 in json['pendingCertChainInfos']],
                activeCertInfo = raritan.rpc.cert.ServerSSLCert.CertInfo.decode(json['activeCertInfo'], agent),
                activeCertChainInfos = [raritan.rpc.cert.ServerSSLCert.CertInfo.decode(x0, agent) for x0 in json['activeCertChainInfos']],
                maxSignDays = json['maxSignDays'],
            )
            return obj

        def encode(self):
            json = {}
            json['havePendingReq'] = self.havePendingReq
            json['havePendingCert'] = self.havePendingCert
            json['pendingReqInfo'] = raritan.rpc.cert.ServerSSLCert.ReqInfo.encode(self.pendingReqInfo)
            json['pendingCertInfo'] = raritan.rpc.cert.ServerSSLCert.CertInfo.encode(self.pendingCertInfo)
            json['pendingCertChainInfos'] = [raritan.rpc.cert.ServerSSLCert.CertInfo.encode(x0) for x0 in self.pendingCertChainInfos]
            json['activeCertInfo'] = raritan.rpc.cert.ServerSSLCert.CertInfo.encode(self.activeCertInfo)
            json['activeCertChainInfos'] = [raritan.rpc.cert.ServerSSLCert.CertInfo.encode(x0) for x0 in self.activeCertChainInfos]
            json['maxSignDays'] = self.maxSignDays
            return json

    class _generateUnsignedKeyPair(Interface.Method):
        name = 'generateUnsignedKeyPair'

        @staticmethod
        def encode(reqInfo, challenge):
            typecheck.is_struct(reqInfo, raritan.rpc.cert.ServerSSLCert.ReqInfo, AssertionError)
            typecheck.is_string(challenge, AssertionError)
            args = {}
            args['reqInfo'] = raritan.rpc.cert.ServerSSLCert.ReqInfo.encode(reqInfo)
            args['challenge'] = challenge
            return args

        @staticmethod
        def decode(rsp, agent):
            _ret_ = rsp['_ret_']
            typecheck.is_int(_ret_, DecodeException)
            return _ret_

    class _generateSelfSignedKeyPair(Interface.Method):
        name = 'generateSelfSignedKeyPair'

        @staticmethod
        def encode(reqInfo, days):
            typecheck.is_struct(reqInfo, raritan.rpc.cert.ServerSSLCert.ReqInfo, AssertionError)
            typecheck.is_int(days, AssertionError)
            args = {}
            args['reqInfo'] = raritan.rpc.cert.ServerSSLCert.ReqInfo.encode(reqInfo)
            args['days'] = days
            return args

        @staticmethod
        def decode(rsp, agent):
            _ret_ = rsp['_ret_']
            typecheck.is_int(_ret_, DecodeException)
            return _ret_

    class _deletePending(Interface.Method):
        name = 'deletePending'

        @staticmethod
        def encode():
            args = {}
            return args

        @staticmethod
        def decode(rsp, agent):
            return None

    class _getInfo(Interface.Method):
        name = 'getInfo'

        @staticmethod
        def encode():
            args = {}
            return args

        @staticmethod
        def decode(rsp, agent):
            info = raritan.rpc.cert.ServerSSLCert.Info.decode(rsp['info'], agent)
            typecheck.is_struct(info, raritan.rpc.cert.ServerSSLCert.Info, DecodeException)
            return info

    class _installPendingKeyPair(Interface.Method):
        name = 'installPendingKeyPair'

        @staticmethod
        def encode():
            args = {}
            return args

        @staticmethod
        def decode(rsp, agent):
            _ret_ = rsp['_ret_']
            typecheck.is_int(_ret_, DecodeException)
            return _ret_
    def __init__(self, target, agent):
        super(ServerSSLCert, self).__init__(target, agent)
        self.generateUnsignedKeyPair = ServerSSLCert._generateUnsignedKeyPair(self)
        self.generateSelfSignedKeyPair = ServerSSLCert._generateSelfSignedKeyPair(self)
        self.deletePending = ServerSSLCert._deletePending(self)
        self.getInfo = ServerSSLCert._getInfo(self)
        self.installPendingKeyPair = ServerSSLCert._installPendingKeyPair(self)

# from raritan/rpc/cert/__extend__.py
def upload(agent, certData, keyData=None):
    """
    Method to upload certificates

    - **parameters**, **return**

    :param agent: An agent instance for the device where the certificate should be uploaded
    :param certData: The binary data of the certificate
    :param keyData: The binary data of the key (optional, default: None)
    :return: the response code

    - **Example**
        :Example:

        from raritan import rpc
        from raritan.rpc import cert

        agent = rpc.Agent("https", "my-pdu.example.com", "admin", "raritan")
        ssl_proxy = cert.ServerSSLCert("/server_ssl_cert", agent)

        # read files in binary mode
        certFile = open("my-cert.crt", "rb")
        keyFile = open("my-key.key", "rb")
        # upload
        code = cert.upload(agent, certFile.read(), keyFile.read())
        # view code
        print(code)
    """
    target = "cgi-bin/server_ssl_cert_upload.cgi"
    formdata = [dict(data=certData, filename="cert-file.crt", formname="cert_file", mimetype="application/octet-stream")]
    if keyData:
        formdata.append(dict(data=keyData, filename="key-file.key", formname="key_file", mimetype="application/octet-stream"))
    response = agent.form_data_file(target, formdata)
    # extract the result from "return_code=<code>" from body
    respBody = response["body"].split("=")
    return int(respBody[1])

def download(agent, tag="active_cert"):
    """
    Method to download the server cert

    **parameters**

    :param agent: An agent instance from the device where the certificate file should be downloaded
    :param tag: The tag to define what should be downloaded
    (default: "active_cert", values: "active_cert","active_key","new_cert","new_key","new_req")
    :return: returns the certificate data

    **Example**
        :Example:

        from raritan import rpc
        from raritan.rpc import cert

        agent = rpc.Agent("https", "my-pdu.example.com", "admin", "raritan")
        # download
        cert = cert.download(agent, "active_cert")
        print(cert)
    """
    target = "cgi-bin/server_ssl_cert_download.cgi?tag=%s" % tag
    return agent.get(target)
