"""Two WordPress accounts sharing one email address.

An address is a way to sign in here, and the login backend refuses to guess
between two accounts holding one. So importing a duplicate as-is does not just
create a tidy-up job — it silently stops email sign-in working for the person
who was already there. The importer drops the contested address instead, and
says so.
"""
import json
import os
import tempfile

from django.contrib.auth import get_user_model
from django.core.management import call_command
from django.test import TestCase

User = get_user_model()


def run_import(users):
    manifest = {"project": "test", "users": users, "categories": [], "documents": []}
    directory = tempfile.mkdtemp(prefix="hartling-import-")
    path = os.path.join(directory, "manifest.json")
    with open(path, "w") as handle:
        json.dump(manifest, handle)
    call_command("import_wordpress", "--manifest", path, "--skip-files", verbosity=0)


def wp_user(username, email, wp_id=1):
    return {
        "wp_id": wp_id, "username": username, "email": email,
        "password_hash": "$P$BexampleexampleexampleexampleX", "hash_format": "phpass",
        "capabilities": "", "registered": "2020-01-01 00:00:00",
        "first_name": "", "last_name": "",
    }


class ImportEmailConflictTests(TestCase):
    def test_the_later_account_is_imported_without_the_contested_address(self):
        User.objects.create_user("first", email="shared@example.com", password="pw-12345678")
        run_import([wp_user("second", "shared@example.com", wp_id=2)])

        self.assertEqual(User.objects.get(username="first").email, "shared@example.com")
        self.assertEqual(User.objects.get(username="second").email, "")

    def test_the_duplicate_account_is_still_imported(self):
        """Dropping the address must not drop the person — they may own documents."""
        User.objects.create_user("first", email="shared@example.com", password="pw-12345678")
        run_import([wp_user("second", "shared@example.com", wp_id=2)])
        self.assertTrue(User.objects.filter(username="second").exists())

    def test_two_duplicates_inside_one_manifest(self):
        run_import([
            wp_user("alpha", "shared@example.com", wp_id=1),
            wp_user("beta", "shared@example.com", wp_id=2),
        ])
        emails = sorted(u.email for u in User.objects.filter(username__in=["alpha", "beta"]))
        self.assertEqual(emails, ["", "shared@example.com"])

    def test_an_account_keeps_its_own_address_when_re_imported(self):
        """A re-run must not read the account's own address as a clash."""
        run_import([wp_user("solo", "solo@example.com")])
        run_import([wp_user("solo", "solo@example.com")])
        self.assertEqual(User.objects.get(username="solo").email, "solo@example.com")

    def test_distinct_addresses_are_untouched(self):
        run_import([
            wp_user("one", "one@example.com", wp_id=1),
            wp_user("two", "two@example.com", wp_id=2),
        ])
        self.assertEqual(User.objects.get(username="one").email, "one@example.com")
        self.assertEqual(User.objects.get(username="two").email, "two@example.com")

    def test_a_signed_in_owner_can_still_be_found_by_their_address(self):
        """The condition the login backend needs: exactly one match."""
        User.objects.create_user("first", email="shared@example.com", password="pw-12345678")
        run_import([wp_user("second", "shared@example.com", wp_id=2)])
        self.assertEqual(User.objects.filter(email__iexact="shared@example.com").count(), 1)
