use bitflags::bitflags;
use foreign_types::ForeignTypeRef;
use libc::{c_int, c_long, c_ulong};
use std::mem;
use std::ptr;

use crate::asn1::Asn1GeneralizedTimeRef;
use crate::error::ErrorStack;
use crate::hash::MessageDigest;
use crate::stack::StackRef;
use crate::util::ForeignTypeRefExt;
use crate::x509::store::X509StoreRef;
use crate::x509::{X509Ref, X509};
use crate::{cvt, cvt_p};
use openssl_macros::corresponds;

bitflags! {
    #[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    #[repr(transparent)]
    pub struct OcspFlag: c_ulong {
        const NO_CERTS = ffi::OCSP_NOCERTS;
        const NO_INTERN = ffi::OCSP_NOINTERN;
        const NO_CHAIN = ffi::OCSP_NOCHAIN;
        const NO_VERIFY = ffi::OCSP_NOVERIFY;
        const NO_EXPLICIT = ffi::OCSP_NOEXPLICIT;
        const NO_CA_SIGN = ffi::OCSP_NOCASIGN;
        const NO_DELEGATED = ffi::OCSP_NODELEGATED;
        const NO_CHECKS = ffi::OCSP_NOCHECKS;
        const TRUST_OTHER = ffi::OCSP_TRUSTOTHER;
        const RESPID_KEY = ffi::OCSP_RESPID_KEY;
        const NO_TIME = ffi::OCSP_NOTIME;
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct OcspResponseStatus(c_int);

impl OcspResponseStatus {
    pub const SUCCESSFUL: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SUCCESSFUL);
    pub const MALFORMED_REQUEST: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_MALFORMEDREQUEST);
    pub const INTERNAL_ERROR: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_INTERNALERROR);
    pub const TRY_LATER: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_TRYLATER);
    pub const SIG_REQUIRED: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_SIGREQUIRED);
    pub const UNAUTHORIZED: OcspResponseStatus =
        OcspResponseStatus(ffi::OCSP_RESPONSE_STATUS_UNAUTHORIZED);

    pub fn from_raw(raw: c_int) -> OcspResponseStatus {
        OcspResponseStatus(raw)
    }

    #[allow(clippy::trivially_copy_pass_by_ref)]
    pub fn as_raw(&self) -> c_int {
        self.0
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct OcspCertStatus(c_int);

impl OcspCertStatus {
    pub const GOOD: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_GOOD);
    pub const REVOKED: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_REVOKED);
    pub const UNKNOWN: OcspCertStatus = OcspCertStatus(ffi::V_OCSP_CERTSTATUS_UNKNOWN);

    pub fn from_raw(raw: c_int) -> OcspCertStatus {
        OcspCertStatus(raw)
    }

    #[allow(clippy::trivially_copy_pass_by_ref)]
    pub fn as_raw(&self) -> c_int {
        self.0
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct OcspRevokedStatus(c_int);

impl OcspRevokedStatus {
    pub const NO_STATUS: OcspRevokedStatus = OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_NOSTATUS);
    pub const UNSPECIFIED: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_UNSPECIFIED);
    pub const KEY_COMPROMISE: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_KEYCOMPROMISE);
    pub const CA_COMPROMISE: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CACOMPROMISE);
    pub const AFFILIATION_CHANGED: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_AFFILIATIONCHANGED);
    pub const STATUS_SUPERSEDED: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_SUPERSEDED);
    pub const STATUS_CESSATION_OF_OPERATION: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CESSATIONOFOPERATION);
    pub const STATUS_CERTIFICATE_HOLD: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_CERTIFICATEHOLD);
    pub const REMOVE_FROM_CRL: OcspRevokedStatus =
        OcspRevokedStatus(ffi::OCSP_REVOKED_STATUS_REMOVEFROMCRL);

    pub fn from_raw(raw: c_int) -> OcspRevokedStatus {
        OcspRevokedStatus(raw)
    }

    #[allow(clippy::trivially_copy_pass_by_ref)]
    pub fn as_raw(&self) -> c_int {
        self.0
    }
}

pub struct OcspStatus<'a> {
    /// The overall status of the response.
    pub status: OcspCertStatus,
    /// If `status` is `CERT_STATUS_REVOKED`, the reason for the revocation.
    pub reason: OcspRevokedStatus,
    /// If `status` is `CERT_STATUS_REVOKED`, the time at which the certificate was revoked.
    pub revocation_time: Option<&'a Asn1GeneralizedTimeRef>,
    /// The time that this revocation check was performed.
    pub this_update: &'a Asn1GeneralizedTimeRef,
    /// The time at which this revocation check expires.
    pub next_update: &'a Asn1GeneralizedTimeRef,
}

impl<'a> OcspStatus<'a> {
    /// Checks validity of the `this_update` and `next_update` fields.
    ///
    /// The `nsec` parameter specifies an amount of slack time that will be used when comparing
    /// those times with the current time to account for delays and clock skew.
    ///
    /// The `maxsec` parameter limits the maximum age of the `this_update` parameter to prohibit
    /// very old responses.
    #[corresponds(OCSP_check_validity)]
    pub fn check_validity(&self, nsec: u32, maxsec: Option<u32>) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::OCSP_check_validity(
                self.this_update.as_ptr(),
                self.next_update.as_ptr(),
                nsec as c_long,
                maxsec.map(|n| n as c_long).unwrap_or(-1),
            ))
            .map(|_| ())
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::OCSP_BASICRESP;
    fn drop = ffi::OCSP_BASICRESP_free;

    pub struct OcspBasicResponse;
    pub struct OcspBasicResponseRef;
}

impl OcspBasicResponseRef {
    /// Verifies the validity of the response.
    ///
    /// The `certs` parameter contains a set of certificates that will be searched when locating the
    /// OCSP response signing certificate. Some responders do not include this in the response.
    #[corresponds(OCSP_basic_verify)]
    pub fn verify(
        &self,
        certs: &StackRef<X509>,
        store: &X509StoreRef,
        flags: OcspFlag,
    ) -> Result<(), ErrorStack> {
        unsafe {
            cvt(ffi::OCSP_basic_verify(
                self.as_ptr(),
                certs.as_ptr(),
                store.as_ptr(),
                flags.bits(),
            ))
            .map(|_| ())
        }
    }

    /// Looks up the status for the specified certificate ID.
    #[corresponds(OCSP_resp_find_status)]
    pub fn find_status<'a>(&'a self, id: &OcspCertIdRef) -> Option<OcspStatus<'a>> {
        unsafe {
            let mut status = ffi::V_OCSP_CERTSTATUS_UNKNOWN;
            let mut reason = ffi::OCSP_REVOKED_STATUS_NOSTATUS;
            let mut revocation_time = ptr::null_mut();
            let mut this_update = ptr::null_mut();
            let mut next_update = ptr::null_mut();

            let r = ffi::OCSP_resp_find_status(
                self.as_ptr(),
                id.as_ptr(),
                &mut status,
                &mut reason,
                &mut revocation_time,
                &mut this_update,
                &mut next_update,
            );
            if r == 1 {
                let revocation_time = Asn1GeneralizedTimeRef::from_const_ptr_opt(revocation_time);

                Some(OcspStatus {
                    status: OcspCertStatus(status),
                    reason: OcspRevokedStatus(status),
                    revocation_time,
                    this_update: Asn1GeneralizedTimeRef::from_ptr(this_update),
                    next_update: Asn1GeneralizedTimeRef::from_ptr(next_update),
                })
            } else {
                None
            }
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::OCSP_CERTID;
    fn drop = ffi::OCSP_CERTID_free;

    pub struct OcspCertId;
    pub struct OcspCertIdRef;
}

impl OcspCertId {
    /// Constructs a certificate ID for certificate `subject`.
    #[corresponds(OCSP_cert_to_id)]
    pub fn from_cert(
        digest: MessageDigest,
        subject: &X509Ref,
        issuer: &X509Ref,
    ) -> Result<OcspCertId, ErrorStack> {
        unsafe {
            cvt_p(ffi::OCSP_cert_to_id(
                digest.as_ptr(),
                subject.as_ptr(),
                issuer.as_ptr(),
            ))
            .map(OcspCertId)
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::OCSP_RESPONSE;
    fn drop = ffi::OCSP_RESPONSE_free;

    pub struct OcspResponse;
    pub struct OcspResponseRef;
}

impl OcspResponse {
    /// Creates an OCSP response from the status and optional body.
    ///
    /// A body should only be provided if `status` is `RESPONSE_STATUS_SUCCESSFUL`.
    #[corresponds(OCSP_response_create)]
    pub fn create(
        status: OcspResponseStatus,
        body: Option<&OcspBasicResponseRef>,
    ) -> Result<OcspResponse, ErrorStack> {
        unsafe {
            ffi::init();

            cvt_p(ffi::OCSP_response_create(
                status.as_raw(),
                body.map(|r| r.as_ptr()).unwrap_or(ptr::null_mut()),
            ))
            .map(OcspResponse)
        }
    }

    from_der! {
        /// Deserializes a DER-encoded OCSP response.
        #[corresponds(d2i_OCSP_RESPONSE)]
        from_der,
        OcspResponse,
        ffi::d2i_OCSP_RESPONSE
    }
}

impl OcspResponseRef {
    to_der! {
        /// Serializes the response to its standard DER encoding.
        #[corresponds(i2d_OCSP_RESPONSE)]
        to_der,
        ffi::i2d_OCSP_RESPONSE
    }

    /// Returns the status of the response.
    #[corresponds(OCSP_response_status)]
    pub fn status(&self) -> OcspResponseStatus {
        unsafe { OcspResponseStatus(ffi::OCSP_response_status(self.as_ptr())) }
    }

    /// Returns the basic response.
    ///
    /// This will only succeed if `status()` returns `RESPONSE_STATUS_SUCCESSFUL`.
    #[corresponds(OCSP_response_get1_basic)]
    pub fn basic(&self) -> Result<OcspBasicResponse, ErrorStack> {
        unsafe { cvt_p(ffi::OCSP_response_get1_basic(self.as_ptr())).map(OcspBasicResponse) }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::OCSP_REQUEST;
    fn drop = ffi::OCSP_REQUEST_free;

    pub struct OcspRequest;
    pub struct OcspRequestRef;
}

impl OcspRequest {
    #[corresponds(OCSP_REQUEST_new)]
    pub fn new() -> Result<OcspRequest, ErrorStack> {
        unsafe {
            ffi::init();

            cvt_p(ffi::OCSP_REQUEST_new()).map(OcspRequest)
        }
    }

    from_der! {
        /// Deserializes a DER-encoded OCSP request.
        #[corresponds(d2i_OCSP_REQUEST)]
        from_der,
        OcspRequest,
        ffi::d2i_OCSP_REQUEST
    }
}

impl OcspRequestRef {
    to_der! {
        /// Serializes the request to its standard DER encoding.
        #[corresponds(i2d_OCSP_REQUEST)]
        to_der,
        ffi::i2d_OCSP_REQUEST
    }

    #[corresponds(OCSP_request_add0_id)]
    pub fn add_id(&mut self, id: OcspCertId) -> Result<&mut OcspOneReqRef, ErrorStack> {
        unsafe {
            let ptr = cvt_p(ffi::OCSP_request_add0_id(self.as_ptr(), id.as_ptr()))?;
            mem::forget(id);
            Ok(OcspOneReqRef::from_ptr_mut(ptr))
        }
    }
}

foreign_type_and_impl_send_sync! {
    type CType = ffi::OCSP_ONEREQ;
    fn drop = ffi::OCSP_ONEREQ_free;

    pub struct OcspOneReq;
    pub struct OcspOneReqRef;
}
