import {
  getConnectivityServices,
  getSipDetail,
  getSips,
} from './dcs'
import {
  getDevices,
  getPorts,
} from './onos'


/**
 * Provide onos port list along with sip uuid.
 * @returns {Promise<*[]>}
 */
export function getResources() {

  return Promise.all([getDevices(), getSips()])
    .then(([devices, sips]) => {
      if(!devices || !sips){
        throw new Error('Device not found')
      }
      const promisePorts = Promise.all(devices.map(device => {
        return getPorts(device.id)
      }))
      const promiseSipDetails = Promise.all(sips.map(sip => {
        return getSipDetail(sip.uuid)
      }))
      return Promise.all([promisePorts, promiseSipDetails, getConnectivityServices()])
    })
    .then(([deviceDetails, sipDetails, connectivityService]) => {

      const dsrSipIdMap = sipDetails
        .filter(filterSipsByLayer.bind(null, "DSR"))
        .reduce((_sipIdMap, sipDetail) => {
          _sipIdMap[sipDetail.name.filter(kv => kv["value-name"] === "onos-cp")[0].value] = sipDetail.uuid
          return _sipIdMap
        }, {})
      const mediaSipIdMap = sipDetails
        .filter(filterSipsByLayer.bind(null, "PHOTONIC_MEDIA"))
        .reduce((_sipIdMap, sipDetail) => {
          _sipIdMap[sipDetail.name.filter(kv => kv["value-name"] === "onos-cp")[0].value] = sipDetail.uuid
          return _sipIdMap
        }, {})
      const portMap = {}

      console.log('DSR SIP ID Map', dsrSipIdMap)
      console.log('PhotinicMedia SIP ID Map', mediaSipIdMap)

      deviceDetails.forEach(deviceDetail => {
        deviceDetail.ports.forEach(port => {
          const key = `${port.element}/${port.port}`
          if(dsrSipIdMap[key]) {
            port.sipId = dsrSipIdMap[key]
          }
          if(mediaSipIdMap[key]) {
            port.mediaSipId = mediaSipIdMap[key]
          }
          portMap[key] = port
        })
      })

      deviceDetails.forEach(deviceDetail => {
        deviceDetail.ports.filter(filterClientSidePort).forEach(cliPort => {
          const linePortKey = `${cliPort.element}/${parseInt(cliPort.port) + 100}`
          cliPort.associatedLinePort = portMap[linePortKey]
        })
      })

      return [ deviceDetails || [], connectivityService || [] ]
    })
    .catch(err => {
      console.error(err)
    })

}

function filterClientSidePort(port) {
  return Math.floor( parseInt(port.port) / 100 ) === 1
}

function filterSipsByLayer(layerProtocolName, sipDetail) {
  return sipDetail["layer-protocol-name"] === layerProtocolName
}