//Execute sync code inside BAS context.
//May execute several times in parallel.
//Result can be obtained by executing _execute_sync_result in code
//And then listening to BrowserAutomationStudio_ExecuteSyncResult
// Example:
// const id = (Math.floor(Math.random() * (1000000000 - 100)) + 100).toString()
// BrowserAutomationStudio_ExecuteSync(id, `var res = 2+2; _execute_sync_result("${id}", res);`)
function BrowserAutomationStudio_ExecuteSync(id, code) {
    BrowserAutomationStudio_ExecuteSyncInternal(id, code)
    return id
}

function BrowserAutomationStudio_ExecuteSyncResult(id, result) {

}

/**
 * Run `code` inside BAS synchronously and get its result as a Promise.
 *
 * @param {string} code          Code that will be executed with _execute_sync_result(), -BAS-EXECUTESYNC-ID- will be replaced with the id.
 * @param {number=} timeout      Timeout in ms; omit or pass null → wait forever.
 * @returns {Promise<{result:any, was_timeout:boolean}>}
 * 
 * example:
 * const { result, was_timeout } = await BrowserAutomationStudio_ExecuteSyncCode('var res = 2+2; _execute_sync_result("-BAS-EXECUTESYNC-ID-", res);', 1000);
 */
function BrowserAutomationStudio_ExecuteSyncCode(code, timeout) {
    // ---------- lazy‑initialise shared state & result hook ----------
    if (!BrowserAutomationStudio_ExecuteSyncCode._waiters) {
      BrowserAutomationStudio_ExecuteSyncCode._waiters = new Map();
  
      // keep any earlier handler alive so nothing breaks
      const prevHandler =
        typeof BrowserAutomationStudio_ExecuteSyncResult === "function"
          ? BrowserAutomationStudio_ExecuteSyncResult
          : null;
  
      // global callback BAS fires when _execute_sync_result(res) is called
      globalThis.BrowserAutomationStudio_ExecuteSyncResult = function (id, result) {
        const waiter = BrowserAutomationStudio_ExecuteSyncCode._waiters.get(id);
        if (waiter) {
          waiter.resolve({ result: JSON.parse(result), was_timeout: false });
          clearTimeout(waiter.timer);
          BrowserAutomationStudio_ExecuteSyncCode._waiters.delete(id);
        }
        if (prevHandler) prevHandler(id, result); // preserve previous behaviour
      };
    }
  
    // ----------------- create promise for this execution -----------------
    const id = (Math.random() * 1e12 >>> 0).toString(36); // fast unique id
  
    return new Promise((resolve) => {
      // store resolver so the global hook can finish the promise
      const record = { resolve, timer: null };
      BrowserAutomationStudio_ExecuteSyncCode._waiters.set(id, record);
  
      // optional timeout
      if (typeof timeout === "number" && timeout >= 0) {
        record.timer = setTimeout(() => {
          BrowserAutomationStudio_ExecuteSyncCode._waiters.delete(id);
          resolve({ result: null, was_timeout: true });
        }, timeout);
      }
  
      // finally send code to BAS
      BrowserAutomationStudio_ExecuteSync(id, code.replace(/-BAS-EXECUTESYNC-ID-/g, id));
    });
  }