import { stringCompare } from "../../shared/src/string-compare.js";
import { readonlyArray, readonlyObject, test } from "../../shared/src/valita.js";
import { deepFreeze } from "./frozen-json.js";
import { getClients, setClients } from "./persist/clients.js";
import { clientIDSchema, clientGroupIDSchema } from "./sync/ids.js";
const DELETED_CLIENTS_HEAD_NAME = "deleted-clients-v2";
const deletedClientsSchema = readonlyArray(
  readonlyObject({
    clientGroupID: clientGroupIDSchema,
    clientID: clientIDSchema
  })
);
function compare(a, b) {
  const cg = stringCompare(a.clientGroupID, b.clientGroupID);
  if (cg !== 0) {
    return cg;
  }
  return stringCompare(a.clientID, b.clientID);
}
function normalizeDeletedClients(deletedClients) {
  return [...deletedClients].sort(compare).filter(
    (item, index) => index === 0 || compare(item, [...deletedClients].sort(compare)[index - 1]) !== 0
  );
}
function mergeDeletedClients(a, b) {
  const merged = [];
  a = normalizeDeletedClients(a);
  b = normalizeDeletedClients(b);
  for (let i = 0, j = 0; i < a.length || j < b.length; ) {
    if (i < a.length && (j >= b.length || compare(a[i], b[j]) < 0)) {
      merged.push(a[i]);
      i++;
    } else if (j < b.length && (i >= a.length || compare(b[j], a[i]) < 0)) {
      merged.push(b[j]);
      j++;
    } else {
      merged.push(a[i]);
      i++;
      j++;
    }
  }
  return merged;
}
async function setDeletedClients(dagWrite, deletedClients) {
  const data = normalizeDeletedClients(deletedClients);
  const chunkData = deepFreeze(data);
  const chunk = dagWrite.createChunk(chunkData, []);
  await dagWrite.putChunk(chunk);
  await dagWrite.setHead(DELETED_CLIENTS_HEAD_NAME, chunk.hash);
  return data;
}
async function getDeletedClients(dagRead) {
  const hash = await dagRead.getHead(DELETED_CLIENTS_HEAD_NAME);
  if (hash === void 0) {
    return [];
  }
  const chunk = await dagRead.mustGetChunk(hash);
  const res = test(chunk.data, deletedClientsSchema);
  if (!res.ok) {
    return [];
  }
  return res.value;
}
async function addDeletedClients(dagWrite, deletedClientsToAdd) {
  const oldDeletedClients = await getDeletedClients(dagWrite);
  return setDeletedClients(
    dagWrite,
    mergeDeletedClients(oldDeletedClients, deletedClientsToAdd)
  );
}
async function confirmDeletedClients(dagWrite, deletedClientIds, deletedClientGroupIds) {
  const deletedClientIDSet = new Set(deletedClientIds);
  const deletedClientGroupIDSet = new Set(deletedClientGroupIds);
  const oldDeletedClients = await getDeletedClients(dagWrite);
  const clients = new Map(await getClients(dagWrite));
  for (const clientID of deletedClientIds) {
    clients.delete(clientID);
  }
  for (const clientGroupID of deletedClientGroupIds) {
    for (const [clientID, client] of clients) {
      if (client.clientGroupID === clientGroupID) {
        clients.delete(clientID);
      }
    }
  }
  await setClients(clients, dagWrite);
  return setDeletedClients(
    dagWrite,
    oldDeletedClients.filter(
      ({ clientGroupID, clientID }) => !deletedClientGroupIDSet.has(clientGroupID) && !deletedClientIDSet.has(clientID)
    )
  );
}
export {
  DELETED_CLIENTS_HEAD_NAME,
  addDeletedClients,
  confirmDeletedClients,
  deletedClientsSchema,
  getDeletedClients,
  mergeDeletedClients,
  normalizeDeletedClients,
  setDeletedClients
};
//# sourceMappingURL=deleted-clients.js.map
