var __awaiter = this && this.__awaiter || function (thisArg, _arguments, P, generator) {
  function adopt(value) {
    return value instanceof P ? value : new P(function (resolve) {
      resolve(value);
    });
  }

  return new (P || (P = Promise))(function (resolve, reject) {
    function fulfilled(value) {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    }

    function rejected(value) {
      try {
        step(generator["throw"](value));
      } catch (e) {
        reject(e);
      }
    }

    function step(result) {
      result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
    }

    step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
};

import { getFeedUpdateChunkReference } from "./index.js";
import { readUint64BigEndian } from "../utils/uint64.js";
import { bytesToHex } from "../utils/hex.js";

function makeNumericIndex(index) {
  if (index instanceof Uint8Array) {
    return readUint64BigEndian(index);
  }

  if (typeof index === 'string') {
    return parseInt(index);
  }

  if (typeof index === 'number') {
    return index;
  }

  throw new TypeError('Unknown type of index!');
}
/**
 * Function that checks if a chunk is retrievable by actually downloading it.
 * The /stewardship/{reference} endpoint does not support verification of chunks, but only manifest's references.
 *
 * @param bee
 * @param ref
 * @param options
 */


function isChunkRetrievable(bee, ref, options) {
  return __awaiter(this, void 0, void 0, function* () {
    try {
      yield bee.downloadChunk(ref, options);
      return true;
    } catch (e) {
      const err = e;

      if (err.status === 404) {
        return false;
      }

      throw e;
    }
  });
}
/**
 * Creates array of references for all sequence updates chunk up to the given index.
 *
 * @param owner
 * @param topic
 * @param index
 */


function getAllSequenceUpdateReferences(owner, topic, index) {
  const numIndex = makeNumericIndex(index);
  const updateReferences = new Array(numIndex + 1);

  for (let i = 0; i <= numIndex; i++) {
    updateReferences[i] = bytesToHex(getFeedUpdateChunkReference(owner, topic, i));
  }

  return updateReferences;
}

export function areAllSequentialFeedsUpdateRetrievable(bee, owner, topic, index, options) {
  return __awaiter(this, void 0, void 0, function* () {
    const chunkRetrievablePromises = getAllSequenceUpdateReferences(owner, topic, index).map(ref => __awaiter(this, void 0, void 0, function* () {
      return isChunkRetrievable(bee, ref, options);
    }));
    return (yield Promise.all(chunkRetrievablePromises)).every(result => result);
  });
}