#!/usr/bin/env python3
#
# Copyright (C) 2023 Savoir-faire Linux Inc.
#
# Author: Xavier Jouslin de Noray <xavier.jouslindenoray@savoirfairelinux.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# Creates packaging targets for a distribution and architecture.
# This helps reduce the length of the top Makefile.
#
import os
from typing import List, Tuple, Optional
from OpenSSL import crypto
from zipfile import ZipFile


from utils import read, save, save_archive, read_archive
from abstactCertificate import AbstractCertificate
from certificate import Certificate
from certificateSigningRequestSignature import CertificateSigningRequestSignature

class CertificateSigningRequest(AbstractCertificate):
    """
    A class representing a certificate signing request.
    """

    def __init__(self, key: Optional[crypto.PKey], cert: Optional[crypto.X509Req]):
        self._cert = cert
        self._key = key

    @property
    def cert(self) -> Tuple[crypto.PKey, crypto.X509Req]:
        """
        Get the certificate.
        :return: A tuple containing the certificate and the key.
        """
        return self._key, self._cert

    @staticmethod
    def load(file_path: str) -> 'CertificateSigningRequest':
        """
        Load a certificate request from a file.
        :param file_path: The path to the certificate request file.
        :return: A Certificate object.
        """
        cert = crypto.load_certificate_request(crypto.FILETYPE_PEM, read(f'{file_path}.csr', 'rb'))
        if not cert.verify(cert.get_pubkey()):
            raise ValueError
        return CertificateSigningRequest(None, cert)

    @staticmethod
    def create(subject: List[Tuple[str, str]], issuer: Optional['AbstractCertificate'] = None) -> 'CertificateSigningRequest':
        """
        Create a new certificate.
        :param subject: A list of tuples containing the subject attributes.
        :param issuer: The issuer certificate.
        :return: A Certificate signing object.
        """
        if issuer is not None:
            raise ValueError
        key = crypto.PKey()
        key.generate_key(crypto.TYPE_RSA, 4096)
        req = crypto.X509Req()
        subj = req.get_subject()
        for attr, info in subject:
            if info is None:
                continue
            if attr == 'crlDistributionPoints':
                # add CRL distribution points extension
                ext = crypto.X509Extension(b'crlDistributionPoints', False, info.encode())
                req.add_extensions([ext])
                continue
            setattr(subj, attr, info)
        req.set_pubkey(key)
        req.sign(key, 'sha512')
        return CertificateSigningRequest(key, req)

    def save(self, path_2_file: str) -> None:
        """
        Save the certificate request to a file.
        :param path_2_file: The path to the file.
        :return: None
        """
        if self._cert is None:
            raise ValueError
        save(f'{path_2_file}.csr', crypto.dump_certificate_request(crypto.FILETYPE_PEM, self._cert), 'wb')
        if self._key is not None:
            save(f'{path_2_file}.key', crypto.dump_privatekey(crypto.FILETYPE_PEM, self._key),'wb')

    def verify(self) -> bool:
        """
        Verify the certificate signing request.
        :return: True if the certificate is valid, False otherwise.
        """
        if self._cert is None:
            return False
        try:
            verified = self._cert.verify(self._cert.get_pubkey())
        except Exception:
            return False
        return verified is None

    def save_archive(self, path_2_file: str):
        """
        Save the certificate request archive.
        :param path_2_file: The path to the file.
        :return: None
        """
        if self._cert is None:
            raise ValueError
        self.save(path_2_file)
        save_archive(f'{path_2_file}.csr.gz', crypto.dump_certificate_request(crypto.FILETYPE_PEM, self._cert), 'wb')

    def verify_from_archive(self, path_2_archive: str) -> bool:
        data = read_archive(path_2_archive)
        path_2_archive = path_2_archive[0:-4]
        save(path_2_archive, data)
        with ZipFile(path_2_archive, 'r') as zip_file:
            filename = os.path.splitext(os.path.basename(path_2_archive))[0]
            self._cert = crypto.load_certificate(crypto.FILETYPE_PEM, read(zip_file.extract(filename + '.crt')))
            return self.verify()

    def sign(self, issuer: 'Certificate') -> 'CertificateSigningRequestSignature':
        """
        Sign the certificate signing request.
        :param issuer: The issuer certificate.
        :param serial: The serial number.
        :param validity: The validity of the certificate.
        :return: A Certificate object.
        """
        return CertificateSigningRequestSignature(issuer).create(self)
