#!/bin/bash
# cf-cse-batch.sh — fetch one MPN's CAD bundle via Mouser CSE with inline-credential
# auth. Bypasses the chrome-error / silent-fail issue caused by the CSE Basic-Auth
# popup being invisible to browser_eval.
#
# Usage:
#   ./cf-cse-batch.sh <MPN> "<Manufacturer Name>"
#
# Output: pulls LIB_<part-variant>.zip into chip-fetcher/incoming/, then distributes
# .kicad_sym / .kicad_mod / .SchLib / .PcbLib / .IntLib / .lbr into library/<MPN>/.

set -u
MPN="${1:?MPN required}"
MFR="${2:?manufacturer required}"
SESSION="chip-fetcher"

# Pull creds + urlencode (write JSON to a tmp file to avoid bash quote-mangling of the python script)
CRED_JSON=$(mktemp)
curl -s http://127.0.0.1:8786/api/credentials > "$CRED_JSON"
CRED=$(python3 - "$CRED_JSON" <<'PYEOF'
import sys, json, urllib.parse
d = json.load(open(sys.argv[1]))
c = next((x for x in d['credentials'] if 'componentsearchengine' in x['host']), None)
if c:
    u = urllib.parse.quote(c['username'], safe='')
    p = urllib.parse.quote(c['password'], safe='')
    print(f"{u}:{p}")
PYEOF
)
rm -f "$CRED_JSON"
[[ -z "$CRED" ]] && { echo "ERROR: no CSE creds in vault"; exit 1; }

MFR_URL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$MFR', safe=''))")
MPN_URL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$MPN', safe=''))")

# Step 1: Navigate to CSE search with inline creds
SEARCH_URL="https://${CRED}@mouser.componentsearchengine.com/entry_u_newDesign.php?mna=${MFR_URL}&mpn=${MPN_URL}&pna=mouser&vrq=multi&fmt=zip&o3=0&logo=&lang=en-GB&epm=0"
adom-desktop browser_navigate "{\"sessionId\":\"$SESSION\",\"url\":\"$SEARCH_URL\"}" >/dev/null 2>&1
sleep 3

# Step 2: Find first variant (skipping header row) + click to preview
FIRST_PART=$(adom-desktop browser_eval "{\"sessionId\":\"$SESSION\",\"expr\":\"(()=>{const rows=Array.from(document.querySelectorAll('tr')); for(const r of rows){const td=r.querySelector('td'); if(td && /^[A-Za-z0-9]/.test(td.textContent.trim())) return td.textContent.trim();} return '';})()\"}" 2>/dev/null \
  | python3 -c "import sys,json; print(json.load(sys.stdin).get('result','').strip())")
if [[ -z "$FIRST_PART" ]]; then
  echo "ERROR: no variants found for $MPN ($MFR) on Mouser CSE"
  exit 2
fi

# Click first DATA row's Download button (filter out header row)
adom-desktop browser_eval "{\"sessionId\":\"$SESSION\",\"expr\":\"(()=>{const rows=Array.from(document.querySelectorAll('tr')); for(const r of rows){const td=r.querySelector('td'); if(td && /^[A-Za-z0-9]/.test(td.textContent.trim())){const btn=r.querySelector('a, button'); if(btn){btn.click(); return 'clicked';}}} return 'no btn';})()\"}" >/dev/null 2>&1
sleep 3

# Step 3: Extract tok + partID from preview's hidden form
META=$(adom-desktop browser_eval "{\"sessionId\":\"$SESSION\",\"expr\":\"(()=>{const f=document.getElementById('zipForm'); if(!f) return null; const get=n=>f.querySelector('input[name='+n+']')?.value; return JSON.stringify({partID:get('partID'),tok:get('tok')});})()\"}" 2>/dev/null \
  | python3 -c "import sys,json; print(json.load(sys.stdin).get('result',''))")
PART_ID=$(echo "$META" | python3 -c "import sys,json; print(json.loads(sys.stdin.read() or '{}').get('partID',''))" 2>/dev/null)
TOK=$(echo "$META"     | python3 -c "import sys,json; print(json.loads(sys.stdin.read() or '{}').get('tok',''))"     2>/dev/null)
if [[ -z "$PART_ID" || -z "$TOK" ]]; then
  echo "ERROR: $MPN ($MFR) — preview form missing partID/tok (got '$META')"
  exit 3
fi
echo "  partID=$PART_ID tok=$TOK ($FIRST_PART)"

# Step 4: Mark a unix-second checkpoint BEFORE triggering the download, then
# use desktop_pull_glob (adom-desktop v1.5+) to wait for the matching file
# AND pull it in one shot. No PowerShell, no shell_execute, no user prompt.
BEFORE=$(date +%s)

DL="https://${CRED}@mouser.componentsearchengine.com/ga/model.php?partID=${PART_ID}&partner=Mouser&tok=${TOK}&emb=1&lang=en-GB&pna=Mouser"
adom-desktop browser_navigate "{\"sessionId\":\"$SESSION\",\"url\":\"$DL\"}" >/dev/null 2>&1

cd /home/adom/project/chip-fetcher
PULL=$(adom-desktop desktop_pull_glob "{\"path\":\"%USERPROFILE%\\\\Downloads\",\"glob\":\"LIB_*.zip\",\"since\":$BEFORE,\"wait\":true,\"timeoutMs\":60000,\"saveTo\":\"$(pwd)/incoming/\"}" 2>/dev/null)
ZIP=$(echo "$PULL" | python3 -c "import sys,json; d=json.load(sys.stdin); f=(d.get('files') or [{}])[0]; print(f.get('path',''))")
NEW=$(basename "$ZIP")
if [[ -z "$ZIP" || ! -f "$ZIP" ]]; then
  echo "ERROR: no LIB_*.zip appeared in Downloads after $BEFORE — $PULL"
  exit 4
fi
echo "  download: $NEW"

# Step 5: relativize the zip path so the rest of the script works.
ZIP="incoming/$NEW"
[[ ! -f "$ZIP" ]] && { echo "ERROR: pulled file missing at $ZIP"; exit 5; }

# Step 6: Distribute the format files we don't get from chip-fetcher's import
EXTRACT=$(mktemp -d)
unzip -q -o "$ZIP" -d "$EXTRACT"
LIB="library/$MPN"
mkdir -p "$LIB"
ADDED=""
SCH=$(find "$EXTRACT" -name "*.SchLib" | head -1)
PCB=$(find "$EXTRACT" -name "*.PcbLib" | head -1)
INT=$(find "$EXTRACT" -name "*.IntLib" | head -1)
LBR=$(find "$EXTRACT" -path "*/EAGLE/*.lbr" -o -path "*/SOLIDWORKS*/*.lbr" | head -1)
[[ -n "$SCH" ]] && cp "$SCH" "$LIB/$MPN.SchLib" && ADDED="$ADDED SchLib"
[[ -n "$PCB" ]] && cp "$PCB" "$LIB/$MPN.PcbLib" && ADDED="$ADDED PcbLib"
[[ -n "$INT" ]] && cp "$INT" "$LIB/$MPN.IntLib" && ADDED="$ADDED IntLib"
[[ -n "$LBR" ]] && cp "$LBR" "$LIB/$MPN.lbr"    && ADDED="$ADDED lbr"
rm -rf "$EXTRACT"
echo "  distributed:$ADDED"
echo "OK: $MPN"