"""
Snippet tuner: given a snippet, a target length, and a target difficulty %,
tells you exactly how many chars to add/remove and how many difficult chars
to add/remove.
"""
SHIFTED = set('~!@#$%^&*()_+{}|:"<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ')
REACH = set('0123456789[]=-`')
RARE = set('\\|`~^')
DIFFICULT = SHIFTED | REACH | RARE

def tune(s, target_len, target_pct):
    dc = sum(1 for c in s if c in DIFFICULT)
    L = len(s)
    pct = round(dc / L * 100, 1)

    # What we need
    lo, hi = target_len - 5, target_len + 5
    need_len_min, need_len_max = lo, hi
    ideal_len = target_len

    # At ideal_len, how many diff chars do we need?
    ideal_diff = round(target_pct * ideal_len / 100)

    # At current length, how many diff chars?
    need_diff_for_current = round(target_pct * L / 100)

    len_delta = ideal_len - L
    diff_delta = ideal_diff - dc

    print(f"  Current: len={L} diff={dc} pct={pct}%")
    print(f"  Target:  len={lo}-{hi} pct={target_pct}% (±1.5%)")
    print(f"  Need:    {'+' if len_delta>=0 else ''}{len_delta} chars total, {'+' if diff_delta>=0 else ''}{diff_delta} difficult chars")

    # Show what range of diff chars works at various lengths
    for test_len in range(lo, hi+1):
        min_diff = int((target_pct - 1.5) * test_len / 100)
        max_diff = int((target_pct + 1.5) * test_len / 100) + 1
        if test_len == L:
            marker = " <-- current"
        else:
            marker = ""
        print(f"    len={test_len}: need {min_diff}-{max_diff} diff chars{marker}")

    print(f"  Difficult chars: {''.join(c for c in s if c in DIFFICULT)}")
    print()
    return L, dc, pct

# Test snippets that need fixing
snippets_to_tune = {
    "novice": (120, 10, [
        "cat /var/log/auth.log | grep -rn 'failed' | sort | tail -20 | tee /tmp/ssh.scan.log; echo 'filtered login entries saved now'",
    ]),
}

for tier, (tl, tp, snips) in snippets_to_tune.items():
    print(f"=== {tier.upper()} ===")
    for s in snips:
        tune(s, tl, tp)
