import { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'
import { sleep } from '@things-factory/utils'
import PWaitFor from 'p-wait-for'

const debug = require('debug')('aidoop:robotics:flow-sync-wait')

async function FlowSyncWait(step, { logger, domain, closures, state }) {
  var { connection } = step

  var connectionInstance = ConnectionManager.getConnectionInstanceByName(domain, connection)
  if (!connectionInstance) {
    throw Error(`connection is not found : ${connectionInstance}`)
  }

  var syncWaitCount = connectionInstance.params.syncWaitCount || 0
  connectionInstance.waitCount += 1
  logger.info(`waiting for other flow-sync-wait(${connectionInstance.waitCount}/${syncWaitCount})`)

  // 시나리오를 임의로 STOP할 경우 PWaitFor를 통해서 대기 상태를 풀어주기 위한 코드를 closures에 등록합니다.
  var exitFlag: boolean = false
  closures.push(async () => {
    exitFlag = true
  })

  debug('1. check-before: ', connectionInstance.waitCount, connectionInstance.releaseCount)

  await PWaitFor(async () => connectionInstance.waitCount >= syncWaitCount || exitFlag === true)
  logger.info(`go to next step from (step: ${step.name}, connection: ${step.connection})`)

  // releaseCount는 모든 대기 중인 시나리오가 풀어지는 것을 확인하고 다시 초기화되어 대기 상태로 들어갈 수 있도록 설정합니다.
  // waitCount는 releaseCount의 영향을 받아서 초기화됩니다.
  connectionInstance.releaseCount += 1

  debug('2. add-rels-cnt: ', connectionInstance.waitCount, connectionInstance.releaseCount)

  if (connectionInstance.releaseCount === connectionInstance.waitCount) {
    connectionInstance.waitCount = connectionInstance.releaseCount = 0
  }

  debug('3. reset-cnt-if: ', connectionInstance.waitCount, connectionInstance.releaseCount)

  exitFlag = null

  return {
    data: {
      ...connectionInstance.waitCount
    }
  }
}

FlowSyncWait.parameterSpec = []

FlowSyncWait.help = 'integration/task/flow-sync-wait'

TaskRegistry.registerTaskHandler('flow-sync-wait', FlowSyncWait)
