"use strict";

exports.__esModule = true;
exports.hubJobImportMocks = hubJobImportMocks;
var _http = require("@wix/bex-utils/@wix/ambassador-hub-v1-job/http");
var _types = require("@wix/bex-utils/@wix/ambassador-hub-v1-job/types");
const UPLOAD_BASE = 'https://import-upload.test';
const UPLOAD_PATH = '/file';
const FILE_ID = 'file-1';
const JOB_ID = 'job-1';
/**
 * Test mocks for the data-hub Hub Job import lifecycle, mirroring
 * `exportServiceMocks`. Auto-included in the test container's httpClient
 * scenarios so every import test drives a fake server. Behavior is controllable
 * per test via `setOutcome` / `setInProgressPolls`, and the uploaded (aligned)
 * CSV + the submitted job request are captured for assertions.
 */
function hubJobImportMocks(whenRequest, when) {
  const state = {
    outcome: 'completed',
    succeeded: 0,
    failed: 0,
    /** number of IN_PROGRESS polls before the job goes terminal */
    inProgressPolls: 0,
    /** csvRows indices reported as failed via movement logs */
    failedRowIndices: [],
    /** the raw body PUT to the signed upload URL (the aligned CSV File) */
    uploadedBody: undefined,
    /** the SubmitJobRequest payload */
    submittedRequest: undefined,
    submittedJobId: undefined,
    terminatedJobIds: []
  };
  const pollCounts = new Map();
  const terminalStatus = () => state.outcome === 'failed' ? _types.JobStatus.FAILED : state.outcome === 'partial' ? _types.JobStatus.PARTIALLY_SUCCESSFUL : _types.JobStatus.COMPLETED;
  const total = () => state.succeeded + state.failed;
  const terminalJob = id => ({
    id,
    status: terminalStatus(),
    progress: {
      current: total(),
      total: total(),
      itemsSuccessful: state.succeeded,
      itemsRejected: state.failed
    },
    ...(state.outcome === 'failed' && {
      error: {
        code: 'import_failed',
        description: 'Import job failed'
      }
    })
  });
  return {
    state,
    /** Set the job's terminal outcome and its success/failure counts. */
    setOutcome(outcome, counts = {}) {
      state.outcome = outcome;
      state.succeeded = counts.succeeded ?? 0;
      state.failed = counts.failed ?? 0;
    },
    /** Make the job report IN_PROGRESS for `n` polls before going terminal. */
    setInProgressPolls(n) {
      state.inProgressPolls = n;
    },
    /** Row indices `listMovementLogs` reports as failed (sourceItemId). */
    setFailedRowIndices(indices) {
      state.failedRowIndices = indices;
    },
    /** The aligned CSV uploaded to the signed URL, as text. */
    async getUploadedCsv() {
      const body = state.uploadedBody;
      if (body == null) {
        return '';
      }
      if (typeof body === 'string') {
        return body;
      }
      const blob = body;
      // jsdom's File implements neither text() nor arrayBuffer() here, so fall
      // back to FileReader.
      if (typeof blob.text === 'function') {
        return blob.text();
      }
      if (typeof blob.arrayBuffer === 'function') {
        return new TextDecoder().decode(await blob.arrayBuffer());
      }
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = () => resolve(String(reader.result));
        reader.onerror = () => reject(reader.error);
        reader.readAsText(blob);
      });
    },
    reset() {
      state.outcome = 'completed';
      state.succeeded = 0;
      state.failed = 0;
      state.inProgressPolls = 0;
      state.failedRowIndices = [];
      state.uploadedBody = undefined;
      state.submittedRequest = undefined;
      state.submittedJobId = undefined;
      state.terminatedJobIds = [];
      pollCounts.clear();
    },
    mocks: [whenRequest(_http.createFileUploadUrl).reply(200, {
      uploadUrl: `${UPLOAD_BASE}${UPLOAD_PATH}`,
      fileId: FILE_ID
    }).persist(), when(UPLOAD_BASE).put(UPLOAD_PATH).reply(200, data => {
      state.uploadedBody = data;
      return {};
    }).persist(), whenRequest(_http.submitJob).reply(200, payload => {
      state.submittedRequest = payload;
      state.submittedJobId = JOB_ID;
      pollCounts.set(JOB_ID, 0);
      return {
        job: {
          id: JOB_ID,
          status: _types.JobStatus.INITIALIZING,
          progress: {
            current: 0,
            total: total()
          }
        }
      };
    }).persist(), whenRequest(_http.getJob).reply(200, payload => {
      const seen = pollCounts.get(payload.jobId) ?? 0;
      pollCounts.set(payload.jobId, seen + 1);
      if (seen < state.inProgressPolls) {
        // No `total` here so ImportState keeps its initial CSV-row total;
        // `current` is 0-based so the first poll reports nothing processed.
        return {
          job: {
            id: payload.jobId,
            status: _types.JobStatus.IN_PROGRESS,
            progress: {
              current: seen,
              itemsSuccessful: seen,
              itemsRejected: 0
            }
          }
        };
      }
      return {
        job: terminalJob(payload.jobId)
      };
    }).persist(), whenRequest(_http.terminateJob).reply(200, payload => {
      state.terminatedJobIds.push(payload.jobId);
      return {};
    }).persist(), whenRequest(_http.listMovementLogs).reply(200, () => ({
      // data-hub formats a CSV item's sourceItemId as "row N", where N is
      // the 1-based file line (header is line 1) — so csvRows[i] is "row i+2".
      logs: state.failedRowIndices.map(index => ({
        sourceItemId: `row ${index + 2}`,
        failure: {
          code: 'row_failed',
          description: 'Invalid row'
        }
      })),
      pagingMetadata: {
        hasNext: false
      }
    })).persist()]
  };
}
//# sourceMappingURL=hubJobImportMocks.js.map