import WebSocketService from '@/domain/services/WebSocketService.js'
import { WebSocket, Server } from 'mock-socket'
import DeviceStateSocketApi from '@/api/websocketApis/DeviceStateSocketApi'
import LinkService from '@/domain/services/LinkService.js'


import {DISCOVER_STATUS_ENUM, ENABLED_STATUS_ENUM} from "../../../../../src/utils/constantCollection";
import Vue from "vue";
import {WS_ADD,WS_ADD_SUCCESS,
  WS_MODIFY_INIT,WS_MODIFY,WS_MODIFY_SUCCESS,
  WS_DELETE_INIT,WS_DELETE,WS_DELETE_SUCCESS,
  WS_DISCOVER,WS_DISCOVER_INIT,WS_DISCOVER_SUCCESS,
  PANIC_MSG,DEVICE_COLLECTION,ALARM_COLLECTION} from "../../../../mock/websocket/wsLinkServiceMock";
import HelperUtil from "../../../../../src/utils/HelperUtil";


describe('LinkWebSocketService', () => {
  const fakeURL = 'ws://localhost:8080'
  var mockServer = null
  var websocketSvc = null

  before(function () {
    // 设置WebSocket为mock-socket提供的WebSocket，以便能够使用假数据测试
    global.WebSocket = WebSocket
  })

  after(function () {
    // 恢复WebSocket为jsdom提供的WebSocket对象
    global.WebSocket = window.WebSocket
  })

  beforeEach(function () {
    mockServer = new Server(fakeURL)
    mockServer.on('connection', function (socket) {
      console.log('server connected')
      socket.on('message', function (data) {
        let msg = JSON.parse(data)
        console.log('server try to respond to', msg)
        if (msg === '0') {
          socket.send(JSON.stringify(WS_ADD))
          console.log('server is sending message:', WS_ADD)
        } else if(msg === '1'){
          socket.send(JSON.stringify(WS_DELETE))
          console.log('server is sending message:', WS_DELETE)
        }else if(msg === '2'){
          socket.send(JSON.stringify(WS_MODIFY))
          console.log('server is sending message:', WS_MODIFY)
        }else if(msg === '7'){
          socket.send(JSON.stringify(WS_DISCOVER))
          console.log('server is sending message:', WS_DISCOVER)
        }else{
          socket.send(JSON.stringify(PANIC_MSG))
          console.log('server is panic')
        }
      })
    })
    websocketSvc = WebSocketService(DeviceStateSocketApi, {URL: fakeURL})
  })

  it('should open', function (done) {
    const WAIT_FINISH_TIME = 100
    const WAIT_SOCKE_OPEN_TIME = 50

    websocketSvc.open()
    expect(websocketSvc.isConnecting()).to.be.true

    setTimeout(() => {
      expect(websocketSvc.isOpen()).to.be.true
    }, WAIT_SOCKE_OPEN_TIME)

    // 延迟结束本测试
    setTimeout(() => {
      mockServer.stop(done)
    }, WAIT_FINISH_TIME)
  })

  it('should AddLink', function (done) {
    const WAIT_FINISH_TIME = 100
    const WAIT_RECEIVE_MSG_TIME = 50

    // subscribe message bark
    let barkMessages = {}
    websocketSvc.subscribe(DeviceStateSocketApi.MsgType.ADD_LINK, barkMessages, (returnObject) => {
      LinkService.updateLinkStatusByAlarmCause(barkMessages, DEVICE_COLLECTION, ALARM_COLLECTION, returnObject)
    });

    // socket打开时发送消息
    websocketSvc.subscribeToOpen(this, function () {
      websocketSvc.send('0')
    })

    // open the socket and send bark to receive bark message
    websocketSvc.open()

    setTimeout(() => {
      // expect(barkMessages).to.have.lengthOf(1)
      // console.log('client received message: ', barkMessages[0])
      expect(barkMessages).to.deep.equal(WS_ADD_SUCCESS)
    }, WAIT_RECEIVE_MSG_TIME)

    // 延迟结束本测试
    setTimeout(() => {
      mockServer.stop(done)
    }, WAIT_FINISH_TIME)
  })

  it('should DeleteLink', function (done) {
    const WAIT_FINISH_TIME = 100
    const WAIT_RECEIVE_MSG_TIME = 50

    // subscribe message bark
    let barkMessages = WS_DELETE_INIT
    websocketSvc.subscribe(DeviceStateSocketApi.MsgType.DELETE_LINK, barkMessages, (returnObject) => {
      for(var i = 0;i<returnObject.length;i++){
        Vue.delete(barkMessages,returnObject[i]);
      }
    });

    // socket打开时发送消息
    websocketSvc.subscribeToOpen(this, function () {
      websocketSvc.send('1')
    })

    // open the socket and send bark to receive bark message
    websocketSvc.open()

    setTimeout(() => {
      // expect(barkMessages).to.have.lengthOf(1)
      // console.log('client received message: ', barkMessages[0])
      expect(barkMessages).to.deep.equal(WS_DELETE_SUCCESS)
    }, WAIT_RECEIVE_MSG_TIME)

    // 延迟结束本测试
    setTimeout(() => {
      mockServer.stop(done)
    }, WAIT_FINISH_TIME)
  })

  it('should ModifyLink', function (done) {
    const WAIT_FINISH_TIME = 100
    const WAIT_RECEIVE_MSG_TIME = 50

    // subscribe message bark
    let barkMessages = WS_MODIFY_INIT
    websocketSvc.subscribe(DeviceStateSocketApi.MsgType.MODIFY_LINK, barkMessages, (returnObject) => {
      let linkKey = returnObject.linkKey;
      barkMessages[linkKey].linkName = returnObject.linkName;
      barkMessages[linkKey].startDeviceKey = returnObject.startDeviceKey;
      barkMessages[linkKey].startPortName = returnObject.startPortName;
      barkMessages[linkKey].endDeviceKey = returnObject.endDeviceKey;
      barkMessages[linkKey].endPortName = returnObject.endPortName;
      barkMessages[linkKey].linkType = returnObject.linkType;
      barkMessages[linkKey].delFlag = returnObject.delFlag;
      barkMessages[linkKey].modifyTime = returnObject.modifyTime;
    });

    // socket打开时发送消息
    websocketSvc.subscribeToOpen(this, function () {
      websocketSvc.send('2')
    })

    // open the socket and send bark to receive bark message
    websocketSvc.open()

    setTimeout(() => {
      // expect(barkMessages).to.have.lengthOf(1)
      // console.log('client received message: ', barkMessages[0])
      expect(barkMessages).to.deep.equal(WS_MODIFY_SUCCESS)
    }, WAIT_RECEIVE_MSG_TIME)

    // 延迟结束本测试
    setTimeout(() => {
      mockServer.stop(done)
    }, WAIT_FINISH_TIME)
  })

  it('should FindLink', function (done) {
    const WAIT_FINISH_TIME = 100
    const WAIT_RECEIVE_MSG_TIME = 50

    // subscribe message bark
    let barkMessages = WS_DISCOVER_INIT
    websocketSvc.subscribe(DeviceStateSocketApi.MsgType.DISCOVER_LINK, barkMessages, (returnObject) => {
      if(!HelperUtil.isFindItemFromCollection(returnObject.linkKey,barkMessages)){
        // 对对象进行字段的补充
        Vue.set(returnObject,'status',DISCOVER_STATUS_ENUM);
        // 将该对象添加到 devices
        Vue.set(barkMessages,returnObject.linkKey,returnObject);
      }
    });

    // socket打开时发送消息
    websocketSvc.subscribeToOpen(this, function () {
      websocketSvc.send('7')
    })

    // open the socket and send bark to receive bark message
    websocketSvc.open()

    setTimeout(() => {
      // expect(barkMessages).to.have.lengthOf(1)
      // console.log('client received message: ', barkMessages[0])
      expect(barkMessages).to.deep.equal(WS_DISCOVER_SUCCESS)
    }, WAIT_RECEIVE_MSG_TIME)

    // 延迟结束本测试
    setTimeout(() => {
      mockServer.stop(done)
    }, WAIT_FINISH_TIME)
  })
})
