import { getIdentity } from '../providers/auth/auth.ic';
import { fromArray, fromNullable, fromTimestamp, toArray, toNullable, toTimestamp } from './did.utils';
import { getDataBucket } from './manager.utils';
export const entries = async ({ startsWith, notContains }) => {
  const identity = getIdentity();
  if (!identity) {
    return [];
  }
  const { actor } = await getDataBucket({ identity });
  if (!actor) {
    return [];
  }
  const data = await actor.list(toNullable({
    startsWith: toNullable(startsWith),
    notContains: toNullable(notContains)
  }));
  const promises = data.map(([, data]) => fromData({ data, identity }));
  const results = await Promise.all(promises);
  return results;
};
const fromData = async ({ data, identity }) => {
  const dataData = await fromArray(data.data);
  return {
    id: data.id,
    data: Object.assign(Object.assign({}, dataData), { owner_id: identity.getPrincipal().toText(), created_at: fromTimestamp(data.created_at), updated_at: fromTimestamp(data.updated_at) })
  };
};
export const deleteData = async ({ key, actor, log }) => {
  if (!key) {
    return;
  }
  log === null || log === void 0 ? void 0 : log({ msg: `[delete] ${key}: start` });
  const t0 = performance.now();
  const dataActor = actor || (await getDataActor());
  await dataActor.del(key);
  const t1 = performance.now();
  log === null || log === void 0 ? void 0 : log({ msg: `[delete] ${key}: done`, duration: t1 - t0 });
};
export const getData = ({ key, actor }) => {
  return new Promise(async (resolve, reject) => {
    try {
      const dataActor = actor || (await getDataActor());
      const entry = fromNullable(await dataActor.get(key));
      if (!entry) {
        resolve(undefined);
        return;
      }
      const data = await fromArray(entry.data);
      resolve({
        id: entry.id,
        data: Object.assign(Object.assign({}, data), { created_at: fromTimestamp(entry.created_at), updated_at: fromTimestamp(entry.updated_at) })
      });
    }
    catch (err) {
      reject(err);
    }
  });
};
export const setData = ({ key, data, id, actor = undefined, log }) => {
  return new Promise(async (resolve, reject) => {
    try {
      log === null || log === void 0 ? void 0 : log({ msg: `[set][start] ${key}` });
      const t0 = performance.now();
      const dataActor = actor || (await getDataActor());
      const now = new Date();
      await dataActor.set(key, {
        id,
        data: await toArray(data),
        created_at: toTimestamp(data.created_at || new Date()),
        updated_at: toTimestamp(now)
      });
      const t1 = performance.now();
      log === null || log === void 0 ? void 0 : log({ msg: `[set][done] ${key}`, duration: t1 - t0 });
      const result = {
        id,
        data: Object.assign(Object.assign({}, data), { updated_at: now })
      };
      resolve(result);
    }
    catch (err) {
      reject(err);
    }
  });
};
const getDataActor = async () => {
  const identity = getIdentity();
  if (!identity) {
    throw new Error('No internet identity.');
  }
  const { actor } = await getDataBucket({ identity });
  if (!actor) {
    throw new Error('No actor initialized.');
  }
  return actor;
};
