"""Search for deleted contacts in Barbara's mailbox using subprocess curl calls."""
import subprocess, json, sys, urllib.parse

CLAUDE_APP = "fabb3421-8b34-484b-bc17-e46de9703418"
CLAUDE_SECRET = "~QJ8Q~NyQSs4OcGqHZyPrA2CVnq9KBfKiimntbMO"
TENANT_ID = "dd4a82e8-85a3-44ac-8800-07945ab4d95f"
USER = "barbara@bardach.net"

def curl_get(url, token, extra_headers=None):
    cmd = ['curl', '-s', '-H', f'Authorization: Bearer {token}']
    if extra_headers:
        for k, v in extra_headers.items():
            cmd.extend(['-H', f'{k}: {v}'])
    cmd.append(url)
    result = subprocess.run(cmd, capture_output=True, text=True)
    return json.loads(result.stdout) if result.stdout.strip() else {}

def curl_post(url, token, body):
    cmd = ['curl', '-s', '-X', 'POST', '-H', f'Authorization: Bearer {token}',
           '-H', 'Content-Type: application/json', '-d', json.dumps(body), url]
    result = subprocess.run(cmd, capture_output=True, text=True)
    return json.loads(result.stdout) if result.stdout.strip() else {}

# Get token
print("[STEP 1] Getting token...")
token_cmd = subprocess.run([
    'curl', '-s', '-X', 'POST',
    f'https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token',
    '-d', f'client_id={CLAUDE_APP}&client_secret={CLAUDE_SECRET}&scope=https://graph.microsoft.com/.default&grant_type=client_credentials'
], capture_output=True, text=True)
token = json.loads(token_cmd.stdout)['access_token']
print("[OK] Token acquired")

# Method 1: Contact folders delta - finds deleted contacts
print("\n[STEP 2] Using contacts delta to enumerate all contacts including deleted...")
delta_url = f"https://graph.microsoft.com/beta/users/{USER}/contacts/delta?$select=displayName,emailAddresses"
all_active = []
all_removed = []
page = 0

while delta_url:
    page += 1
    data = curl_get(delta_url, token)
    if 'error' in data:
        print(f"[ERROR] {data['error'].get('code')}: {data['error'].get('message','')[:200]}")
        break

    items = data.get('value', [])
    for item in items:
        if '@removed' in item:
            all_removed.append(item)
        else:
            all_active.append(item)

    delta_url = data.get('@odata.nextLink')
    delta_token_url = data.get('@odata.deltaLink')

    if page % 5 == 0:
        print(f"  Page {page}: {len(all_active)} active, {len(all_removed)} removed...")

    if not delta_url:
        break

print(f"\n[RESULT] Delta scan complete:")
print(f"  Active contacts: {len(all_active)}")
print(f"  Deleted contacts: {len(all_removed)}")

if all_removed:
    print(f"\n  First 20 deleted contacts:")
    for r in all_removed[:20]:
        name = r.get('displayName', '(no name)')
        rid = r.get('id', '?')[:30]
        reason = r.get('@removed', {}).get('reason', '?')
        print(f"    {name} (reason: {reason})")

# Method 2: Check the Deleted Items folder for contact-class items
# Using the search API which handles IPM.Contact items
print(f"\n[STEP 3] Searching Deleted Items folder via search API...")
search_body = {
    "requests": [{
        "entityTypes": ["message"],
        "query": {"queryString": "kind:contacts"},
        "from": 0,
        "size": 25
    }]
}
search_result = curl_post(f"https://graph.microsoft.com/v1.0/users/{USER}/search/query", token, search_body)
if 'error' in search_result:
    print(f"[INFO] Search API: {search_result['error'].get('code')}: {search_result['error'].get('message','')[:200]}")
elif search_result.get('value'):
    for resp in search_result['value']:
        hits = resp.get('hitsContainers', [{}])
        for hc in hits:
            total = hc.get('total', 0)
            print(f"  Search found {total} contact-related items")
            for hit in hc.get('hits', [])[:10]:
                resource = hit.get('resource', {})
                print(f"    {resource.get('subject', '?')}")
else:
    print(f"[INFO] Search returned: {json.dumps(search_result)[:300]}")
