# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import dbs
from south.v2 import DataMigration
from django.db import models

db = dbs["rpkidb"]

class Migration(DataMigration):

    def forwards(self, orm):
        """
        Copy data from legacy MySQL tables to new models.

        We can handle most of this via trivial SQL-to-SQL copy
        operations, but a few tables don't quite fit into Django
        without adjustment, or require data type conversion that we
        have to push through the model layer.
        """

        if db.backend_name != "mysql":
            return

        tables = set(row[0] for row in db.execute("SHOW TABLES"))

        verbose = False

        def sql_to_sql_copy(table, fields):
            if table in tables:
                fields = ", ".join("`%s`" % field for field in fields)
                sql = "INSERT INTO `rpkidb_%s` (`id`, %s) SELECT `%s_id`, %s FROM `%s`" % (table.translate(None, "_"), fields, table, fields, table)
                if verbose:
                    print "=>", sql
                db.execute(sql)

        sql_to_sql_copy("self",
                        ("self_handle", "use_hsm", "crl_interval", "regen_margin", "bpki_cert", "bpki_glue"))

        # bsc.hash_alg is an enum, so we need to convert representation.

        if "bsc" in tables:
            for (bsc_id, bsc_handle, private_key_id, pkcs10_request, signing_cert, signing_cert_crl, self_id) in db.execute(
                    """
                    SELECT bsc_id, bsc_handle, private_key_id, pkcs10_request, signing_cert, signing_cert_crl, self_id
                    FROM bsc
                    """):
                orm.Bsc.objects.create(
                    id                  = bsc_id,
                    bsc_handle          = bsc_handle,
                    private_key_id      = private_key_id,
                    pkcs10_request      = pkcs10_request,
                    hash_alg            = 1,
                    signing_cert        = signing_cert,
                    signing_cert_crl    = signing_cert_crl,
                    self_id             = self_id)

        sql_to_sql_copy("repository",
                        ("repository_handle", "peer_contact_uri", "bpki_cert", "bpki_glue", "last_cms_timestamp",
                         "bsc_id", "self_id"))

        sql_to_sql_copy("parent",
                        ("parent_handle", "bpki_cms_cert", "bpki_cms_glue", "peer_contact_uri", "sia_base",
                         "sender_name", "recipient_name", "last_cms_timestamp", "self_id", "bsc_id", "repository_id"))

        sql_to_sql_copy("ca",
                        ("last_crl_sn", "last_manifest_sn", "next_manifest_update", "next_crl_update", "last_issued_sn",
                         "sia_uri", "parent_resource_class", "parent_id"))

        # ca_detail.state is an enum, so we need to convert representation.

        if "ca_detail" in tables:
            for (ca_detail_id, public_key, private_key_id, latest_crl, crl_published, latest_ca_cert,
                 manifest_private_key_id, manifest_public_key, latest_manifest_cert, latest_manifest,
                 manifest_published, state, ca_cert_uri, ca_id) in db.execute(
                    """
                    SELECT ca_detail_id, public_key, private_key_id, latest_crl, crl_published, latest_ca_cert,
                           manifest_private_key_id, manifest_public_key, latest_manifest_cert, latest_manifest,
                           manifest_published, state + 0, ca_cert_uri, ca_id
                    FROM ca_detail
                    """):
                orm.CaDetail.objects.create(
                    id                          = ca_detail_id,
                    public_key                  = public_key,
                    private_key_id              = private_key_id,
                    latest_crl                  = latest_crl,
                    crl_published               = crl_published,
                    latest_ca_cert              = latest_ca_cert,
                    manifest_private_key_id     = manifest_private_key_id,
                    manifest_public_key         = manifest_public_key,
                    latest_manifest_cert        = latest_manifest_cert,
                    latest_manifest             = latest_manifest,
                    manifest_published          = manifest_published,
                    state                       = state,
                    ca_cert_uri                 = ca_cert_uri,
                    ca_id                       = ca_id)

        sql_to_sql_copy("child",
                        ("child_handle", "bpki_cert", "bpki_glue", "last_cms_timestamp", "self_id", "bsc_id"))

        sql_to_sql_copy("child_cert",
                        ("cert", "published", "ski", "child_id", "ca_detail_id"))

        sql_to_sql_copy("revoked_cert",
                        ("serial", "revoked", "expires", "ca_detail_id"))

        sql_to_sql_copy("roa",
                        ("asn", "cert", "roa", "published", "self_id", "ca_detail_id"))

        sql_to_sql_copy("ghostbuster",
                        ("vcard", "cert", "ghostbuster", "published", "self_id", "ca_detail_id"))

        sql_to_sql_copy("ee_cert",
                        ("ski", "cert", "published", "self_id", "ca_detail_id"))

        # roa_prefix needs special handling because Django doesn't
        # handle compound primary keys, so we have to synthesize one.
        # This is a bit nasty, don't read if you've eaten recently.

        if "roa_prefix" in tables:
            sql = """
                  INSERT INTO `rpkidb_roaprefix`
                  (`id`, `prefix`, `prefixlen`, `max_prefixlen`, `version`, `roa_id`)
                  SELECT
                  @current_row := @current_row + 1 AS
                  `roa_prefix_id`, `prefix`, `prefixlen`, `max_prefixlen`, `version`, `roa_id`
                  FROM `roa_prefix`
                  JOIN (SELECT @current_row := 0) AS `table_alias_required_here_but_ignored`
                  ORDER BY `roa_id`, `prefix`, `prefixlen`, `max_prefixlen`
                  """
            if verbose:
                print "=>", sql
            db.execute(sql)



    def backwards(self, orm):
        """
        Roll back this migration.  Disabled by default, because it's dangerous.
        """

        enable_dangerous_rollback = False

        if db.backend_name != "mysql":
            return

        elif not enable_dangerous_rollback:
            raise RuntimeError("Reversing this transformation is dangerous, edit %s if you're sure you want to do this" % __file__)

        for table in [row[0] for row in db.execute("SHOW TABLES") if row[0].startswith("rpkidb_")]:
            db.execute("DELETE FROM `%s`" % table)



    models = {
        u'rpkidb.bsc': {
            'Meta': {'unique_together': "((u'self', u'bsc_handle'),)", 'object_name': 'Bsc'},
            'bsc_handle': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
            'hash_alg': ('rpki.fields.EnumField', [], {}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'pkcs10_request': ('rpki.fields.PKCS10Field', [], {'default': 'None', 'blank': 'True'}),
            'private_key_id': ('rpki.fields.KeyField', [], {'default': 'None', 'blank': 'True'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"}),
            'signing_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'signing_cert_crl': ('rpki.fields.CRLField', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
        },
        u'rpkidb.ca': {
            'Meta': {'object_name': 'Ca'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'last_crl_sn': ('django.db.models.fields.BigIntegerField', [], {}),
            'last_issued_sn': ('django.db.models.fields.BigIntegerField', [], {}),
            'last_manifest_sn': ('django.db.models.fields.BigIntegerField', [], {}),
            'next_crl_update': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'next_manifest_update': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Parent']"}),
            'parent_resource_class': ('django.db.models.fields.TextField', [], {}),
            'sia_uri': ('django.db.models.fields.TextField', [], {})
        },
        u'rpkidb.cadetail': {
            'Meta': {'object_name': 'CaDetail'},
            'ca': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Ca']"}),
            'ca_cert_uri': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
            'crl_published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'latest_ca_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'latest_crl': ('rpki.fields.CRLField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'latest_manifest': ('rpki.fields.ManifestField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'latest_manifest_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'manifest_private_key_id': ('rpki.fields.KeyField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'manifest_public_key': ('rpki.fields.KeyField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'manifest_published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'private_key_id': ('rpki.fields.KeyField', [], {'default': 'None', 'blank': 'True'}),
            'public_key': ('rpki.fields.KeyField', [], {'default': 'None', 'blank': 'True'}),
            'state': ('rpki.fields.EnumField', [], {})
        },
        u'rpkidb.child': {
            'Meta': {'unique_together': "((u'self', u'child_handle'),)", 'object_name': 'Child'},
            'bpki_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'bpki_glue': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'bsc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Bsc']"}),
            'child_handle': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'last_cms_timestamp': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"})
        },
        u'rpkidb.childcert': {
            'Meta': {'object_name': 'ChildCert'},
            'ca_detail': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.CaDetail']"}),
            'cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'child': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Child']"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'ski': ('rpki.fields.BlobField', [], {'default': 'None', 'blank': 'True'})
        },
        u'rpkidb.eecert': {
            'Meta': {'object_name': 'EeCert'},
            'ca_detail': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.CaDetail']"}),
            'cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"}),
            'ski': ('rpki.fields.BlobField', [], {'default': 'None', 'blank': 'True'})
        },
        u'rpkidb.ghostbuster': {
            'Meta': {'object_name': 'Ghostbuster'},
            'ca_detail': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.CaDetail']"}),
            'cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'ghostbuster': ('rpki.fields.GhostbusterField', [], {'default': 'None', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"}),
            'vcard': ('django.db.models.fields.TextField', [], {})
        },
        u'rpkidb.parent': {
            'Meta': {'unique_together': "((u'self', u'parent_handle'),)", 'object_name': 'Parent'},
            'bpki_cms_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'bpki_cms_glue': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'bsc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Bsc']"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'last_cms_timestamp': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'parent_handle': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
            'peer_contact_uri': ('django.db.models.fields.TextField', [], {}),
            'recipient_name': ('django.db.models.fields.TextField', [], {}),
            'repository': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Repository']"}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"}),
            'sender_name': ('django.db.models.fields.TextField', [], {}),
            'sia_base': ('django.db.models.fields.TextField', [], {'blank': 'True'})
        },
        u'rpkidb.repository': {
            'Meta': {'unique_together': "((u'self', u'repository_handle'),)", 'object_name': 'Repository'},
            'bpki_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'bpki_glue': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'bsc': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Bsc']"}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'last_cms_timestamp': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'peer_contact_uri': ('django.db.models.fields.TextField', [], {}),
            'repository_handle': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"})
        },
        u'rpkidb.revokedcert': {
            'Meta': {'object_name': 'RevokedCert'},
            'ca_detail': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.CaDetail']"}),
            'expires': ('rpki.fields.SundialField', [], {}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'revoked': ('rpki.fields.SundialField', [], {}),
            'serial': ('django.db.models.fields.BigIntegerField', [], {})
        },
        u'rpkidb.roa': {
            'Meta': {'object_name': 'Roa'},
            'asn': ('django.db.models.fields.BigIntegerField', [], {}),
            'ca_detail': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.CaDetail']"}),
            'cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'published': ('rpki.fields.SundialField', [], {'null': 'True', 'blank': 'True'}),
            'roa': ('rpki.fields.ROAField', [], {'default': 'None', 'blank': 'True'}),
            'self': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Self']"})
        },
        u'rpkidb.roaprefix': {
            'Meta': {'object_name': 'RoaPrefix'},
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'max_prefixlen': ('django.db.models.fields.IntegerField', [], {}),
            'prefix': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
            'prefixlen': ('django.db.models.fields.IntegerField', [], {}),
            'roa': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['rpkidb.Roa']"}),
            'version': ('django.db.models.fields.IntegerField', [], {})
        },
        u'rpkidb.self': {
            'Meta': {'object_name': 'Self'},
            'bpki_cert': ('rpki.fields.CertificateField', [], {'default': 'None', 'blank': 'True'}),
            'bpki_glue': ('rpki.fields.CertificateField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
            'crl_interval': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'regen_margin': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
            'self_handle': ('django.db.models.fields.SlugField', [], {'max_length': '255'}),
            'use_hsm': ('django.db.models.fields.IntegerField', [], {})
        }
    }

    complete_apps = ['rpkidb']
    symmetrical = True
