"""sshj.jsonio — state-dir constants + JSON I/O (leaf).

B2 step 1: moved verbatim from sshj_cli.py (single-file era) — no behavior
change. Owns the state-dir constants because both lastused and identity
need them and they must live in a leaf (no intra-project imports).
"""
import json
import os

STATE_DIR = os.path.expanduser(os.environ.get("SSHJ_STATE_DIR", "~/.local/state/sshj"))
LAST_USED_FILE = os.path.join(STATE_DIR, "last_used.json")
LAST_SUCCESS_FILE = os.path.join(STATE_DIR, "last_success.json")
IDENTITY_FILE = os.path.join(STATE_DIR, "identity.json")


def update_needed():
    """True if an update is flagged (SSHJ_UPDATE=1 or flag file); no network."""
    if os.environ.get("SSHJ_UPDATE") == "1":
        return True
    if os.path.exists(os.path.join(STATE_DIR, "update.flag")):
        return True
    return False  # TODO: real release check


def load_json(path, default):
    """Read JSON, or return `default` on any error (never raises)."""
    try:
        with open(path) as f:
            return json.load(f)
    except Exception:
        return default


def save_json(path, data):
    """Atomic JSON write (tmp + os.replace); creates parent dirs."""
    os.makedirs(os.path.dirname(path), exist_ok=True)
    tmp = path + ".tmp"
    with open(tmp, "w") as f:
        json.dump(data, f, indent=1)
    os.replace(tmp, path)
