"""
First cut at Django ORM models for rpkid.
"""

from __future__ import unicode_literals
from django.db import models
from django.conf import settings
from south.modelsinspector import add_introspection_rules, NOT_PROVIDED

from rpki.fields import (EnumField, SundialField, BlobField,
                         CertificateField, KeyField, CRLField, PKCS10Field,
                         ManifestField, ROAField, GhostbusterField)


# "self" was a really bad name for this, but we weren't using Python
# when we named it.  Perhaps "Tenant" would be a better name?  Even
# means sort of the right thing, well, in French anyway.
# Eventually rename in left-right too, I guess.

class Self(models.Model):
    self_handle = models.SlugField(max_length = 255)
    use_hsm = models.IntegerField()
    crl_interval = models.BigIntegerField(blank = True, null = True)
    regen_margin = models.BigIntegerField(blank = True, null = True)
    bpki_cert = CertificateField()
    bpki_glue = CertificateField(null = True)

class Bsc(models.Model):
    bsc_handle = models.SlugField(max_length = 255)
    private_key_id = KeyField()
    pkcs10_request = PKCS10Field()
    hash_alg = EnumField(choices = ("sha256",))
    signing_cert = CertificateField(null = True)
    signing_cert_crl = CRLField(null = True)
    self = models.ForeignKey(Self)
    class Meta:
        unique_together = ("self", "bsc_handle")

class Repository(models.Model):
    repository_handle = models.SlugField(max_length = 255)
    peer_contact_uri = models.TextField()
    bpki_cert = CertificateField()
    bpki_glue = CertificateField(null = True)
    last_cms_timestamp = SundialField(blank = True, null = True)
    bsc = models.ForeignKey(Bsc)
    self = models.ForeignKey(Self)
    class Meta:
        unique_together = ("self", "repository_handle")

class Parent(models.Model):
    parent_handle = models.SlugField(max_length = 255)
    bpki_cms_cert = CertificateField()
    bpki_cms_glue = CertificateField(null = True)
    peer_contact_uri = models.TextField()
    sia_base = models.TextField(blank = True)
    sender_name = models.TextField()
    recipient_name = models.TextField()
    last_cms_timestamp = SundialField(blank = True, null = True)
    self = models.ForeignKey(Self)
    bsc = models.ForeignKey(Bsc)
    repository = models.ForeignKey(Repository)
    class Meta:
        unique_together = ("self", "parent_handle")

class Ca(models.Model):
    last_crl_sn = models.BigIntegerField()
    last_manifest_sn = models.BigIntegerField()
    next_manifest_update = SundialField(blank = True, null = True)
    next_crl_update = SundialField(blank = True, null = True)
    last_issued_sn = models.BigIntegerField()
    sia_uri = models.TextField()
    parent_resource_class = models.TextField()
    parent = models.ForeignKey(Parent)

class CaDetail(models.Model):
    public_key = KeyField()
    private_key_id = KeyField()
    latest_crl = CRLField(null = True)
    crl_published = SundialField(blank = True, null = True)
    latest_ca_cert = CertificateField(null = True)
    manifest_private_key_id = KeyField(null = True)
    manifest_public_key = KeyField(null = True)
    latest_manifest_cert = CertificateField(null = True)
    latest_manifest = ManifestField(null = True)
    manifest_published = SundialField(blank = True, null = True)
    state = EnumField(choices = ("pending", "active", "deprecated", "revoked"))
    ca_cert_uri = models.TextField(blank = True)
    ca = models.ForeignKey(Ca)

class Child(models.Model):
    child_handle = models.SlugField(max_length = 255)
    bpki_cert = CertificateField()
    bpki_glue = CertificateField(null = True)
    last_cms_timestamp = SundialField(blank = True, null = True)
    self = models.ForeignKey(Self)
    bsc = models.ForeignKey(Bsc)
    class Meta:
        unique_together = ("self", "child_handle")

class ChildCert(models.Model):
    cert = CertificateField()
    published = SundialField(blank = True, null = True)
    ski = BlobField()
    child = models.ForeignKey(Child)
    ca_detail = models.ForeignKey(CaDetail)

class EeCert(models.Model):
    ski = BlobField()
    cert = CertificateField()
    published = SundialField(blank = True, null = True)
    self = models.ForeignKey(Self)
    ca_detail = models.ForeignKey(CaDetail)

class Ghostbuster(models.Model):
    vcard = models.TextField()
    cert = CertificateField()
    ghostbuster = GhostbusterField()
    published = SundialField(blank = True, null = True)
    self = models.ForeignKey(Self)
    ca_detail = models.ForeignKey(CaDetail)

class RevokedCert(models.Model):
    serial = models.BigIntegerField()
    revoked = SundialField()
    expires = SundialField()
    ca_detail = models.ForeignKey(CaDetail)

class Roa(models.Model):
    asn = models.BigIntegerField()
    cert = CertificateField()
    roa = ROAField()
    published = SundialField(blank = True, null = True)
    self = models.ForeignKey(Self)
    ca_detail = models.ForeignKey(CaDetail)

class RoaPrefix(models.Model):
    prefix = models.CharField(max_length=40)
    prefixlen = models.IntegerField()
    max_prefixlen = models.IntegerField()
    version = models.IntegerField()
    roa = models.ForeignKey(Roa)
