"""Shared IG auth helper. Resilient to gql rate-limits."""
import re
from pathlib import Path

from instagrapi import Client


def safe_login(cl: Client, session_path: Path, session_id: str) -> None:
    """Login that survives IG gql/web rate-limits.

    Strategy:
    1. Try to restore from cached settings file. Verify with a private-API call.
       This path skips the gql verify call entirely, so it survives rate limits.
    2. If cache is missing or stale, fresh login_by_sessionid. On success, dump
       settings so next run hits the cache path.
    3. If login_by_sessionid hits a gql rate-limit, recover: cookies are set,
       just manually populate user_id from sessionid + verify via private API.
    """
    # Path 1: cached settings
    if session_path.exists():
        try:
            cl.load_settings(session_path)
            cl.account_info()  # private API verify, no gql
            return
        except Exception:
            pass

    # Path 2: fresh login
    try:
        cl.login_by_sessionid(session_id)
        cl.dump_settings(session_path)
        return
    except Exception as e:
        msg = type(e).__name__ + ": " + str(e)[:200]
        # Path 3: recover from gql failure
        gql_failure = any(
            keyword in msg
            for keyword in ("TooManyRedirects", "Graphql", "BadRequest", "fb_dtsg",
                            "ClientError", "something went wrong")
        )
        if not gql_failure:
            raise

        # manually inject session cookie + set user_id
        m = re.search(r"^(\d+)", session_id)
        if not m:
            raise RuntimeError("could not extract user_id from sessionid") from e
        uid = str(int(m.group(1)))
        cl.set_settings({"user_id": uid})
        # inject cookie directly into private session
        try:
            cl.private.cookies.set("sessionid", session_id, domain=".instagram.com")
        except Exception:
            pass
        try:
            info = cl.account_info()
            try:
                cl.username = getattr(info, "username", None)
            except Exception:
                pass
        except Exception:
            # private API still blocked — proceed anyway, session cookie is set
            cl.username = uid
        cl.dump_settings(session_path)
