import { ConnectionManager, ScenarioInstanceStatus, TaskRegistry } from '@things-factory/integration-base'
import { sleep } from '@things-factory/utils'

import { getTrackingWorkspace } from './get-tracking-workspace'

function getROIState(domain, roi) {
  var workspace = getTrackingWorkspace(domain)
  if (!workspace) {
    /* TODO workspace가 없는 경우와, ROI가 빈 경우에 대한 구분처리가 필요하다. */
    return []
  }

  var { engine } = workspace
  var { trackingStorage } = engine

  return trackingStorage.getROIState(roi).filter(obj => obj.retention > 0)
}

function getROIEvent(domain, roi) {
  var workspace = getTrackingWorkspace(domain)
  if (!workspace) {
    /* TODO workspace가 없는 경우와, ROI가 빈 경우에 대한 구분처리가 필요하다. */
    return []
  }

  var { engine } = workspace
  var { trackingStorage } = engine

  return trackingStorage.getROIEvent(roi)
}

async function TrackingWorkspaceWaitForROI(step, { root, data, domain }) {
  var {
    name,
    connection,
    params: { roi, waitFor }
  } = step

  // keep this previous code by heartyoh to track the changes history
  //   var lastObjects = data[name]

  //   if (!lastObjects) {
  //     lastObjects = getROIState(domain, roi)
  //   }

  //   while (true) {
  //     let state = root.getState()
  //     if (state == 1 /* STARTED */) {
  //       var objects = getROIState(domain, roi)

  //       var evt = getROIEvent(domain, roi)
  //       console.log('*#* evt: ', evt, '[', roi, ']')

  //       var changed =
  //         lastObjects.length !== objects.length ||
  //         objects.find((object, idx) => {
  //           var lastObject = lastObjects[idx]
  //           return object.id != lastObject.id
  //         })

  //       if (changed) {
  //         lastObjects = objects

  //         if (waitFor == 'empty' && objects.length == 0) {
  //           break
  //         } else if (waitFor == 'fill' && objects.length > 0) {
  //           break
  //         }
  //       }

  //       await sleep(1000)
  //     } else if (state == 2 /* PAUSED */) {
  //       await sleep(1000)
  //     } else {
  //       throw new Error('scenario stopped unexpectedly')
  //     }
  //   }
  var object = ConnectionManager.getConnectionInstanceByName(domain, connection) || {}
  if (!object) {
    throw new Error(`no connection : ${connection}`)
  }

  var workspace = getTrackingWorkspace(domain)
  var { engine } = workspace
  var { trackingStorage } = engine

  while (true) {
    let state = root.getState()
    if (state == ScenarioInstanceStatus.STARTED /* STARTED */) {
      var evt = getROIEvent(domain, roi)
      var roiObjCount = trackingStorage.getROIState(roi).length

      //   console.log('*#* evt: ', evt, '[', roi, ']')
      //   console.log('*#* roiObjCount: ', roiObjCount, '[', roi, ']')
      //   console.log('*#* waitFor: ', waitFor, '[', roi, ']')

      if ((waitFor == 'empty' || waitFor == 'fill') && evt) {
        if (waitFor == 'empty' && evt.type == 2 /* 2 means TRACKING_EVENT_TYPES.OUT */) {
          break
        } else if (waitFor == 'fill' && evt.type == 0 /* 0 means TRACKING_EVENT_TYPES.IN */) {
          break
        }
      } else {
        if (waitFor == 'keep-fill' && roiObjCount > 0) {
          break
        } else if (waitFor == 'keep-empty' && roiObjCount == 0) {
          break
        }
      }

      await sleep(1000)
    } else if (state == ScenarioInstanceStatus.STOPPED /* PAUSED */) {
      await sleep(1000)
    } else {
      throw new Error('scenario stopped unexpectedly')
    }
  }

  return {
    data: evt
  }
}

TrackingWorkspaceWaitForROI.parameterSpec = [
  {
    type: 'string',
    name: 'roi',
    label: 'roi'
  },
  {
    type: 'select',
    name: 'waitFor',
    label: 'wait-for',
    property: {
      options: [
        { display: '', value: '' },
        { display: 'Being Fill', value: 'fill' },
        { display: 'Being Empty', value: 'empty' },
        { display: 'Fill', value: 'keep-fill' },
        { display: 'Empty', value: 'keep-empty' }
      ]
    }
  }
]

TrackingWorkspaceWaitForROI.help = 'robotics/task/tracking-workspace-wait-for-roi'

TaskRegistry.registerTaskHandler('tracking-ws-wait-for-roi', TrackingWorkspaceWaitForROI)
