// import {
//   addIndex,
//   findIndex,
//   find,
//   map,
//   propEq,
//   reduce,
//   sort,
//   range,
//   concat,
//   filter,
//   reverse,
//   prop,
//   flatten,
//   uniq,
//   reject,
//   contains,
//   omit,
//   equals,
//   update,
//   times,
//   add,
//   pluck,
//   last, forEach
// } from 'rambda';
// import type { JobId } from '../../types';
// import { max, min, remove, slice } from 'ramda';
// import { createSchedule as johnson, updateCTime } from '../johnson';
//
// type JobTime = {
//   jobId: JobId,
//   t: number,
//   succ: JobId[],
//   processor: number
// };
//
// type JobTimeWithZK = JobTime | {
//   z: number,
//   k: number
// };
//
// const noAncJobs = (jobTimes: JobTime[]) => {
//   const allSuccesors = flatten(map(prop('succ'), jobTimes));
//   return reject((jobTime: JobTime) => contains(jobTime.jobId, allSuccesors), jobTimes);
// };
//
// const ancestors = (id: JobId, jobTimes: JobTime[]) =>
//   filter(({ succ }) => contains(id, succ), jobTimes);
//
// const updateZK = (jobTimes: JobTimeWithZK[], allJobTimes: JobTimeWithZK) =>
//   map((jobTime: JobTimeWithZK) => {
//     // const allSuccesors = map(prop('succ'), jobTimes);
//     const ancestors = filter(aJob => contains(jobTime.jobId, aJob.succ), allJobTimes);
//
//     let z = reduce((acc, job) => max(acc, job.k), -Infinity, ancestors);
//     z = max(z, jobTime.t);
//
//     return {
//       ...jobTime,
//       z,
//       k: z + jobTime.t
//     };
//   }, jobTimes);
//
// export const createSchedule = (jobTimes: JobTime[], processorsCount: number) => {
//   let k = 0;
//   let Pk = [];
//
//   let jobTimesWithZK: JobTimeWithZK[] = map((jobTime: JobTime) => ({
//       ...jobTime,
//       z: 0,
//       k: 0 + jobTime.t
//     }), jobTimes);
//
//   let Sk = noAncJobs(jobTimesWithZK);
//   let mStar;
//
//   const processorC = [0, 0, 0, 0];
//
//   // while (Sk.length) {
//   while (k < 4) {
//     // if (k === 2) {
//     //   console.log(processorC);
//     // }
//     // console.log(processorC);
//     let kStar = reduce((acc: JobTimeWithZK, jobTime: JobTimeWithZK) => {
//       // console.log(jobTime.jobId, jobTime.t + processorC[jobTime.processor]);
//
//       const anc = ancestors(jobTime.jobId, jobTimes)[0];
//       // let z = processorC[jobTime.processor];
//
//       // console.log(jobTime, anc);
//
//       if (anc) {
//         jobTime.k = jobTime.t + anc.k;
//       } else {
//         jobTime.k = jobTime.t;
//       }
//
//         jobTimes.forEach(j => {
//           if (j.jobId === jobTime.jobId) {
//             j.k = jobTime.k
//           }
//         });
//
//         // if (k === 2) {
//         //   console.log(jobTime, anc);
//         // }
//
//       return jobTime.k < acc.k ? jobTime : acc;
//     }
//       // jobTime.t < acc.t ? jobTime : acc
//       // jobTime.k < acc.k ? jobTime : acc
//     , { k: Infinity }, Sk).k;
//
//     if (k === 3)
//       console.log(kStar);
//
//     let oStar = find((jobTime: JobTimeWithZK) => jobTime.k === kStar, Sk);
//     // console.log(oStar);
//     mStar = oStar.processor;
//
//     // processorC[oStar.processor] += oStar.t;
//     // const p = pluck('processor', map(succ => find(propEq('jobId', succ), jobTimes), oStar.succ));
//     // forEach(processor => {
//     //   if (processor !== oStar.processor) {
//     //     return processorC[processor] += oStar.t;
//     //   }
//     // }, p);
//
//     let morePk = filter((jobTime: JobTimeWithZK) =>
//       jobTime.processor === oStar.processor && (jobTime.k - jobTime.t) < kStar
//     , Sk);
//     morePk = updateZK(morePk, jobTimesWithZK);
//
//     Pk = concat(Pk, morePk);
//     let PkIds = pluck('jobId', Pk);
//     let rejectedFromSk = filter((jobTime: JobTimeWithZK) => contains(jobTime.jobId, PkIds), Sk);
//     let rejectedSuccessors = flatten(
//       map(jobTime => map(jobId => find(propEq('jobId', jobId), jobTimesWithZK), jobTime.succ), rejectedFromSk)
//     );
//     // rejectedSuccessors = updateZK(rejectedSuccessors, jobTimesWithZK);
//
//     // Sk = reject(jobTime => jobTime.jobId === oStar.jobId, Sk);
//     Sk = reject((jobTime: JobTimeWithZK) => contains(jobTime.jobId, PkIds), Sk);
//     Sk = concat(Sk, rejectedSuccessors);
//
//     Sk = sort((a, b) => a.jobId > b.jobId, Sk);
//
//     // if (k === 1) {
//     //   console.log(Sk);
//     // }
//
//     k++;
//   }
//
//   // const jobTimesExtended = map((jobTime: JobTime) => {
//   //   return ({
//   //     ...jobTime,
//   //
//   //   })
//   // }, jobTimes);
// };
//
// export default (jobsOperations: JobOperations[], processorsCount: number) => {
//   const schedule = createSchedule(jobsOperations, processorsCount);
//
//   return times(i =>
//     map((jobTime: JobOperationsWithC) => ({
//       processor: i + 1,
//       startTime: jobTime.operations[i].c - jobTime.operations[i].t,
//       endTime: jobTime.operations[i].c,
//     }), schedule)
//   , processorsCount);
// };