"""Shared WordPress -> portal mapping rules.

Single source of truth for how WordPress data becomes portal data, used by both
the extractor (host side) and the import command (container side), and unit
tested on its own. Pure functions — no Django models, no I/O.
"""
import re

# WordPress stores roles as a PHP-serialised array, e.g. a:1:{s:5:"owner";b:1;}
_ROLE_RE = re.compile(r's:\d+:"([^"]+)";b:1')

# Roles that should get access to the staff admin. Everything else (notably the
# custom "owner" role) becomes an ordinary authenticated user with no admin.
STAFF_ROLES = {"administrator", "editor", "hartling group staff"}
SUPERUSER_ROLES = {"administrator"}


def parse_wp_roles(capabilities):
    """['owner'] from a serialised wp_capabilities value. Empty list if unparsable."""
    if not capabilities:
        return []
    return [role.lower() for role in _ROLE_RE.findall(capabilities)]


def wp_hash_to_django(user_pass):
    """Wrap a WordPress password hash so Django routes it to the right verifier.

    Returns None for an empty/unrecognised hash — the caller should import that
    user with an unusable password (they can reset) rather than guess.
    """
    if not user_pass:
        return None
    if user_pass.startswith(("$P$", "$H$")):
        return "wp_phpass$" + user_pass
    if user_pass.startswith(("$wp$", "$2y$", "$2a$", "$2b$")):
        return "wp_bcrypt$" + user_pass
    return None


def hash_format(user_pass):
    """Label for the reconciliation report: phpass / wp6.8 / bcrypt / unknown."""
    if not user_pass:
        return "empty"
    if user_pass.startswith(("$P$", "$H$")):
        return "phpass"
    if user_pass.startswith("$wp$"):
        return "wp6.8"
    if user_pass.startswith(("$2y$", "$2a$", "$2b$")):
        return "bcrypt"
    return "unknown"


def slugify_category(label):
    slug = re.sub(r"[^a-z0-9]+", "-", label.lower()).strip("-")
    return slug or "uncategorised"


def attachment_relpath(attached_file):
    """`_wp_attached_file` is already the path relative to uploads/."""
    return (attached_file or "").lstrip("/")


def relpath_from_upload_url(url):
    """Pull the `YYYY/MM/name.pdf` part out of a legacy full-URL meta value.

    Handles the plain uploads URL and the /bw-file/<id>/<name> protected form
    (which carries no year/month, so it yields just the filename).
    """
    if not url:
        return None
    match = re.search(r"/uploads/(.+)$", url)
    if match:
        return match.group(1).split("?")[0]
    match = re.search(r"/bw-file/\d+/(.+)$", url)
    if match:
        return match.group(1).split("?")[0]
    return None
