import json
import subprocess
from pathlib import Path


PRIVATE_DATA_JS = Path(__file__).resolve().parents[1] / "frontend" / "private-device-data.js"


def test_private_device_data_purger_waits_for_owned_outbox_and_cache_deletion():
    harness = f"""
const createPrivateDeviceDataPurger = require({json.dumps(str(PRIVATE_DATA_JS))});
const state = {{removed:[], databases:[], caches:[], workerMessages:[], order:[], complete:false}};
const storage = {{
  values:new Map([['stackchain.draft','private'],['other.preference','keep']]),
  get length(){{return this.values.size;}},
  key(index){{return Array.from(this.values.keys())[index] || null;}},
  removeItem(key){{state.order.push('storage');state.removed.push(key);this.values.delete(key);}},
}};
const clear = createPrivateDeviceDataPurger({{
  localStorage:storage, sessionStorage:storage,
  indexedDB:{{deleteDatabase:name=>{{
    state.databases.push(name);
    const request={{}};
    setTimeout(()=>{{state.complete=true;request.onsuccess?.();}},10);
    return request;
  }}}},
  caches:{{keys:async()=>['stackchain-dashboard-shell-v37','other-app'],delete:async key=>state.caches.push(key)}},
  serviceWorker:{{ready:Promise.resolve({{active:{{postMessage:(message,ports)=>{{state.order.push('worker');state.workerMessages.push(message);ports[0].postMessage({{ok:true}});}}}}}})}},
  MessageChannel:class{{constructor(){{
    const first={{onmessage:null,postMessage:data=>queueMicrotask(()=>second.onmessage?.({{data}}))}};
    const second={{onmessage:null,postMessage:data=>queueMicrotask(()=>first.onmessage?.({{data}}))}};
    this.port1=first;this.port2=second;
  }}}},
}});
(async()=>{{
  await clear();
  process.stdout.write(JSON.stringify({{...state,remaining:Array.from(storage.values.keys())}}));
}})().catch(error=>{{console.error(error);process.exit(1);}});
"""
    result = subprocess.run(
        ["node", "-e", harness], text=True, capture_output=True, check=True
    )
    state = json.loads(result.stdout)

    assert state["remaining"] == ["other.preference"]
    assert state["databases"] == [
        "stackchain-background-outbox-v1",
        "stackchain-offline-work-v2",
        "stackchain-unfiled-captures-v1",
        "stackchain-voice-transcripts-v1",
        "stackchain-search-reply-drafts-v1",
        "stackchain-conversation-reply-drafts-v1",
        "stackchain-today-action-mailbox-v1",
    ]
    assert state["caches"] == ["stackchain-dashboard-shell-v37"]
    assert state["workerMessages"] == [{"type": "stackchain-purge-outbox"}]
    assert state["order"][0] == "worker"
    assert state["complete"] is True
