import { useContext } from "react";
import { v4 as uuidv4 } from "uuid";
import JobContext from "@qltr/jobctx";
import Initiator from "@qltr/initiator";
import { jobStatus, socketUrl } from "./job-config.js";

export function useOneshotCore() {
  const { state, jobUpdate, jobCreate, jobDelete } = useContext(JobContext);

  function oneshotCancel(jobId) {
    const job = state.jobs.find((j) => j.jobId === jobId);

    if (job.initiator.sk) job.initiator.sk.close();
    job.status = jobStatus.CANCELED;
    jobUpdate({ ...job }, jobId);
  }

  function oneshotDestroy(jobId) {
    const job = state.jobs.find((j) => j.jobId === jobId);
    const { status } = job;
    const isTriggered = !!job.initiator.sk;
    const isCompleted = status === jobStatus.OK || status === jobStatus.ERROR;
    const isCanceled = status === jobStatus.CANCELED;
    if (isTriggered && !isCompleted && !isCanceled) job.initiator.sk.close();
    jobDelete(jobId);
  }

  function oneshotStart(builderCache) {
    const { testNames, isTriage } = builderCache;
    const initiator = new Initiator(socketUrl);
    const jobId = uuidv4();
    const job = {
      name: jobId,
      status: jobStatus.PENDING,
      jobId,
      isPipeline: false,
      builderCache,
      initiator,
    };
    const request = { testNames, type: "single", isTriage };

    jobCreate(job);

    const onLog = (d) => {
      const job = state.jobs.find((j) => j.jobId === jobId);
      job.log.push(d);
      job.status = jobStatus.ACTIVE;
      jobUpdate({ ...job }, jobId);
    };

    const onClose = (c) => {
      const job = state.jobs.find((j) => j.jobId === jobId);
      job.exitcode = c;
      job.status = c === 0 ? jobStatus.OK : jobStatus.ERROR;
      jobUpdate({ ...job }, jobId);
    };

    const started = initiator.newJob(request, onLog, onClose, () => {});
    started.then(() => jobUpdate({ status: jobStatus.ACTIVE }, jobId));
    return jobId;
  }
  return { oneshotStart, oneshotCancel, oneshotDestroy };
}
