# -*- coding: utf-8 -*-
# Generated by Django 1.11.27 on 2020-08-06 13:36
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('account', '0005_secondaryemail'),
        ('core', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='communityauthsite',
            name='apiurl',
            field=models.URLField(max_length=200, null=False, blank=True),
        ),
        migrations.AddField(
            model_name='communityauthsite',
            name='push_changes',
            field=models.BooleanField(default=False, help_text='Supports receiving http POSTs with changes to accounts'),
        ),
        migrations.AddField(
            model_name='communityauthsite',
            name='push_ssh',
            field=models.BooleanField(default=False, help_text='Wants to receive SSH keys in push changes'),
        ),
        migrations.RunSQL(
            """CREATE TABLE account_communityauthchangelog (
   user_id int NOT NULL REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED,
   site_id int NOT NULL REFERENCES account_communityauthsite (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED,
   changedat timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP,
   CONSTRAINT account_communityauthchangelog_pkey PRIMARY KEY (user_id, site_id)
)""",
            """DROP TABLE account_communityauthchangelog""",
        ),

        # When a user entry is changed, propagate it to any community auth site that has push enabled, and that
        # the user has at some point logged in to. We do this through a trigger on auth_user, to make sure we
        # definitely catch all changes.
        migrations.RunSQL(
            """CREATE FUNCTION account_cauth_changetrack () RETURNS trigger AS $$
BEGIN
   IF NEW.username != OLD.username THEN
      RAISE EXCEPTION 'Usernames cannot be changed';
   END IF;

   IF NEW.first_name != OLD.first_name OR NEW.last_name != OLD.last_name OR NEW.email != OLD.email THEN
      INSERT INTO account_communityauthchangelog (user_id, site_id, changedat)
            SELECT NEW.id, s.id, CURRENT_TIMESTAMP
            FROM account_communityauthsite s
            INNER JOIN account_communityauthlastlogin ll ON ll.site_id=s.id
            WHERE s.push_changes AND ll.user_id=NEW.id
       ON CONFLICT (user_id, site_id) DO UPDATE SET changedat=greatest(account_communityauthchangelog.changedat, CURRENT_TIMESTAMP);
      NOTIFY communityauth_changetrack;
   END IF;
   RETURN NEW;
END;
$$ language 'plpgsql'""",
            """DROP FUNCTION account_cauth_changetrack""",
        ),

        # We specifically don't use "UPDATE OF" to find columns because then we create a dependency on columns in
        # auth_user, which is owned by django, and may block migrations in that app. So we make the check at runtime.
        migrations.RunSQL(
            """CREATE TRIGGER account_cauth_changetrack_trg
 AFTER UPDATE ON auth_user
 FOR EACH ROW EXECUTE FUNCTION account_cauth_changetrack()""",
            """DROP TRIGGER account_cauth_changetrack_trg ON auth_user""",
        ),

        # We also need to track when secondary email addresses are added/removed (if they are confirmed)
        # We don't have to track INSERTs as they are always unconfirmed, but we do need to track deletes here.
        migrations.RunSQL(
            """CREATE FUNCTION account_secondaryemail_changetrack () RETURNS trigger AS $$
BEGIN
   INSERT INTO account_communityauthchangelog (user_id, site_id, changedat)
            SELECT OLD.user_id, s.id, CURRENT_TIMESTAMP
            FROM account_communityauthsite s
            INNER JOIN account_communityauthlastlogin ll ON ll.site_id=s.id
            WHERE s.push_changes AND ll.user_id=OLD.user_id
    ON CONFLICT (user_id, site_id) DO UPDATE SET changedat=greatest(account_communityauthchangelog.changedat, CURRENT_TIMESTAMP);
   NOTIFY communityauth_changetrack;
   RETURN NEW;
END;
$$ language 'plpgsql'""",
            """DROP FUNCTION account_secondaryemail_changetrack""",
        ),

        migrations.RunSQL(
            """CREATE TRIGGER account_secondaryemail_changetrack_trg
 AFTER DELETE OR UPDATE ON account_secondaryemail
 FOR EACH ROW EXECUTE FUNCTION account_secondaryemail_changetrack()""",
            """DROP TRIGGER account_Secondaryemail_changetrack_trg""",
        ),

        migrations.RunSQL(
            """CREATE FUNCTION account_profile_changetrack () RETURNS trigger AS $$
BEGIN
   IF NEW.sshkey != OLD.sshkey THEN
      INSERT INTO account_communityauthchangelog (user_id, site_id, changedat)
            SELECT NEW.user_id, s.id, CURRENT_TIMESTAMP
            FROM account_communityauthsite s
            INNER JOIN account_communityauthlastlogin ll ON ll.site_id=s.id
            WHERE s.push_changes AND s.push_ssh AND ll.user_id=NEW.user_id
      ON CONFLICT (user_id, site_id) DO UPDATE SET changedat=greatest(account_communityauthchangelog.changedat, CURRENT_TIMESTAMP);
      NOTIFY communityauth_changetrack;
   END IF;
   RETURN NEW;
END;
$$ language 'plpgsql'""",
            """DROP FUNCTION account_secondaryemail_changetrack""",
        ),

        migrations.RunSQL(
            """CREATE TRIGGER account_profile_changetrack_trg
 AFTER DELETE OR UPDATE ON core_userprofile
 FOR EACH ROW EXECUTE FUNCTION account_profile_changetrack()""",
            """DROP TRIGGER account_profile_changetrack_trg""",
        ),
    ]
