
const { ISource } = require("./port/ISource");
const { OSink } = require("./port/OSink");
const { OSource } = require("./port/OSource");
const { ISink } = require("./port/ISink");

export class PortHub {
  constructor(portType) {
    this.ports = [];
    this.portType = portType;
  }

  init(context) {
    this.context = context;
    for (let i = 0; i < this.ports.length; i++) {
      Object.assign(this.ports[i], context);
      this.ports[i] = this.getPortInstance(this.ports[i]);
    }
  }

  mutationUpdate(portsTemp){
    //合并配置，portId存在则更新，不存在则添加
    for(let port of portsTemp){
      let index = this.ports.findIndex(item => item.portId === port.portId);
      Object.assign(port, this.context);
      let portInstance;
      if(index !== -1){
        //销毁原来的port
        this.ports[index].update(port);
        portInstance=this.ports[index];
      }else{
        portInstance = this.getPortInstance(port);
        this.ports.push(portInstance);
      }
      if(this.portType!=="oSource"){
        portInstance.mutationUpdate(port);
      }
    }
  }

  open() {
    for (let port of this.ports) {
      port.open();
    }
  }

  close() {
    for (let port of this.ports) {
      port.close();
    }
  }
  start(params) {
    for (let port of this.ports) {
      port.start(params);
    }
  }

  query(params) {
    for (let port of this.ports) {
      port.query(params);
    }
  }
  getTaskStatus(params) {
    for (let port of this.ports) {
      port.getTaskStatus(params);
    }
  }
  stop() {
    for (let port of this.ports) {
      port.stop();
    }
  }

  pause() {
    for (let port of this.ports) {
      port.pause();
    }
  }

  resume() {
    for (let port of this.ports) {
      port.resume();
    }
  }

  removeAllListeners(eventName) {
    for (let port of this.ports) {
      port.eventEmitter.removeAllListeners(eventName);
    }
  }

  addPort(port) {
    this.ports.push(port);
    return port;
  }

  removePort(port) {
    this.ports = this.ports.filter((p) => p !== port);
  }

  clearPorts() {
    this.ports = [];
  }

  getPort(index) {
    return this.ports[index];
  }

  getPortCount() {
    return this.ports.length;
  }
  getPortById(portId) {
    return this.ports.find(port => port.portId === portId);
  }
  getPortInstance(port) {
    switch (this.portType) {
      case "iSource":
        return new ISource(port);
      case "oSink":
        return new OSink(port);
      case "oSource":
        return new OSource(port);
      case "iSink":
        return new ISink(port);
      default:
        return port;
    }
  }
}
