# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

import datetime

import pytest

import pytz

from cryptography import x509
from cryptography.hazmat.backends.interfaces import X509Backend


class TestRevokedCertificateBuilder(object):
    def test_serial_number_must_be_integer(self):
        with pytest.raises(TypeError):
            x509.RevokedCertificateBuilder().serial_number("notanx509name")

    def test_serial_number_must_be_non_negative(self):
        with pytest.raises(ValueError):
            x509.RevokedCertificateBuilder().serial_number(-1)

    def test_serial_number_must_be_positive(self):
        with pytest.raises(ValueError):
            x509.RevokedCertificateBuilder().serial_number(0)

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_minimal_serial_number(self, backend):
        revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number(1)
            .revocation_date(revocation_date)
        )

        revoked_certificate = builder.build(backend)
        assert revoked_certificate.serial_number == 1

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_biggest_serial_number(self, backend):
        revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number((1 << 159) - 1)
            .revocation_date(revocation_date)
        )

        revoked_certificate = builder.build(backend)
        assert revoked_certificate.serial_number == (1 << 159) - 1

    def test_serial_number_must_be_less_than_160_bits_long(self):
        with pytest.raises(ValueError):
            x509.RevokedCertificateBuilder().serial_number(1 << 159)

    def test_set_serial_number_twice(self):
        builder = x509.RevokedCertificateBuilder().serial_number(3)
        with pytest.raises(ValueError):
            builder.serial_number(4)

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_aware_revocation_date(self, backend):
        time = datetime.datetime(2012, 1, 16, 22, 43)
        tz = pytz.timezone("US/Pacific")
        time = tz.localize(time)
        utc_time = datetime.datetime(2012, 1, 17, 6, 43)
        serial_number = 333
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number(serial_number)
            .revocation_date(time)
        )

        revoked_certificate = builder.build(backend)
        assert revoked_certificate.revocation_date == utc_time

    def test_revocation_date_invalid(self):
        with pytest.raises(TypeError):
            x509.RevokedCertificateBuilder().revocation_date("notadatetime")

    def test_revocation_date_before_1950(self):
        with pytest.raises(ValueError):
            x509.RevokedCertificateBuilder().revocation_date(
                datetime.datetime(1940, 8, 10)
            )

    def test_set_revocation_date_twice(self):
        builder = x509.RevokedCertificateBuilder().revocation_date(
            datetime.datetime(2002, 1, 1, 12, 1)
        )
        with pytest.raises(ValueError):
            builder.revocation_date(datetime.datetime(2002, 1, 1, 12, 1))

    def test_add_extension_checks_for_duplicates(self):
        builder = x509.RevokedCertificateBuilder().add_extension(
            x509.CRLReason(x509.ReasonFlags.ca_compromise), False
        )

        with pytest.raises(ValueError):
            builder.add_extension(
                x509.CRLReason(x509.ReasonFlags.ca_compromise), False
            )

    def test_add_invalid_extension(self):
        with pytest.raises(TypeError):
            x509.RevokedCertificateBuilder().add_extension(
                "notanextension", False
            )

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_no_serial_number(self, backend):
        builder = x509.RevokedCertificateBuilder().revocation_date(
            datetime.datetime(2002, 1, 1, 12, 1)
        )

        with pytest.raises(ValueError):
            builder.build(backend)

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_no_revocation_date(self, backend):
        builder = x509.RevokedCertificateBuilder().serial_number(3)

        with pytest.raises(ValueError):
            builder.build(backend)

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_create_revoked(self, backend):
        serial_number = 333
        revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number(serial_number)
            .revocation_date(revocation_date)
        )

        revoked_certificate = builder.build(backend)
        assert revoked_certificate.serial_number == serial_number
        assert revoked_certificate.revocation_date == revocation_date
        assert len(revoked_certificate.extensions) == 0

    @pytest.mark.parametrize(
        "extension",
        [
            x509.InvalidityDate(datetime.datetime(2015, 1, 1, 0, 0)),
            x509.CRLReason(x509.ReasonFlags.ca_compromise),
            x509.CertificateIssuer([x509.DNSName(u"cryptography.io")]),
        ],
    )
    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_add_extensions(self, backend, extension):
        serial_number = 333
        revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number(serial_number)
            .revocation_date(revocation_date)
            .add_extension(extension, False)
        )

        revoked_certificate = builder.build(backend)
        assert revoked_certificate.serial_number == serial_number
        assert revoked_certificate.revocation_date == revocation_date
        assert len(revoked_certificate.extensions) == 1
        ext = revoked_certificate.extensions.get_extension_for_class(
            type(extension)
        )
        assert ext.critical is False
        assert ext.value == extension

    @pytest.mark.requires_backend_interface(interface=X509Backend)
    def test_add_multiple_extensions(self, backend):
        serial_number = 333
        revocation_date = datetime.datetime(2002, 1, 1, 12, 1)
        invalidity_date = x509.InvalidityDate(
            datetime.datetime(2015, 1, 1, 0, 0)
        )
        certificate_issuer = x509.CertificateIssuer(
            [x509.DNSName(u"cryptography.io")]
        )
        crl_reason = x509.CRLReason(x509.ReasonFlags.aa_compromise)
        builder = (
            x509.RevokedCertificateBuilder()
            .serial_number(serial_number)
            .revocation_date(revocation_date)
            .add_extension(invalidity_date, True)
            .add_extension(crl_reason, True)
            .add_extension(certificate_issuer, True)
        )

        revoked_certificate = builder.build(backend)
        assert len(revoked_certificate.extensions) == 3
        for ext_data in [invalidity_date, certificate_issuer, crl_reason]:
            ext = revoked_certificate.extensions.get_extension_for_class(
                type(ext_data)
            )
            assert ext.critical is True
            assert ext.value == ext_data
