'use strict'
!(function(require, directRequire) {
  function a(b) {
    if (l) {
      const c = n.get(b)
      if (c) {
        if (c.heartbeatPendingCount > q)
          return (
            d.info(
              `unresponsive client window (id: ${b}) will be disconnected`
            ),
            r({ id: b, projectid: c.projectid, fromAction: !0 }),
            n.delete(b),
            void m.delete(b)
          )
        c.heartbeatPendingCount++,
          (c.timeoutId = setTimeout(a.bind(this, b), p)),
          l.postMessage({ type: e.EVENT_HEARTBEAT, id: b })
      }
    }
  }
  function b(b) {
    const { data: c } = b
    switch (c.type) {
      case e.EVENT_HEARTBEAT: {
        if (c.id) {
          const a = n.get(c.id)
          a && a.heartbeatPendingCount--
        }
        break
      }
      case e.EVENT_DEV_WINDOW_OPENED: {
        c.id &&
          (n.set(c.id, {
            [e.INIT_TIME]: +new Date(),
            id: c.id,
            projectid: c.projectid,
            heartbeatPendingCount: 0
          }),
          m.delete(c.projectid),
          s(),
          a(c.id)),
          o.emit(e.EVENT_DEV_WINDOW_OPENED, c.id),
          o.emit(`${e.EVENT_DEV_WINDOW_OPENED}-${c.id}`, c.id),
          o.emit(`${e.EVENT_DEV_WINDOW_OPENED}-${c.projectid}`, c.projectid)
        break
      }
      case e.EVENT_DEV_WINDOW_CLOSE: {
        r(c)
        break
      }
      case e.EVENT_DEV_WINDOW_CLI_PORT_UPDATE: {
        n.has(c.id)
          ? c[e.CLI_PORT]
            ? ((n.get(c.id)[e.CLI_PORT] = c[e.CLI_PORT]),
              o.emit(
                e.EVENT_DEV_WINDOW_CLI_PORT_UPDATE,
                c.id,
                c.projectid,
                c[e.CLI_PORT]
              ),
              o.emit(
                `${e.EVENT_DEV_WINDOW_CLI_PORT_UPDATE}-${c.id}`,
                c.id,
                c.projectid,
                c[e.CLI_PORT]
              ),
              o.emit(
                `${e.EVENT_DEV_WINDOW_CLI_PORT_UPDATE}-${c.projectid}`,
                c.id,
                c.projectid,
                c[e.CLI_PORT]
              ))
            : d.info(
                `server.sync.js: a dev window notify the update of cli port without an cliPort argument, id: ${
                  c.id
                }`
              )
          : d.info(
              `server.sync.js: a dev window, whose id is not present in client window map, notify the update of cli port: ${
                c.id
              }`
            )
        break
      }
    }
  }
  const c = require('events'),
    d = require('./logger.js'),
    e = require('./09060286633d09fb81fefc8ff1294dd7.js'),
    f = require('./tools.js'),
    g = require('./bc78839ccca8df9e5ceeb7fae11b7be2.js'),
    h = require('./cc2c2970ff81ae4a83123e81ee123da2.js'),
    i = require('./56c390e04c10e91a4aa2a2c19d9a885d.js'),
    j = require('./205e69607c4b60711b15f5ac95b40ce4.js'),
    k = 'darwin' === process.platform
  let l
  const m = new Set(),
    n = new Map(),
    o = new c(),
    p = 6000,
    q = 10,
    r = a => {
      n.has(a.id)
        ? (a.id === j.getCurrentBrowsingContext() &&
            j.setCurrentBrowsingContext(j.getMainWindowHandle()),
          n.delete(a.id),
          d.info(
            `dev window with id ${
              a.id
            } closed, cur ctx: ${j.getCurrentBrowsingContext()}`
          ))
        : d.info(
            `server.sync.js: a dev window whose id is not present in client window map is closed: ${
              a.id
            }`
          ),
        o.emit(e.EVENT_DEV_WINDOW_CLOSE, a.id),
        0 === n.size &&
          (k
            ? a.fromAction &&
              (g.dispatch(h.selectDevType(i.DEV_TYPE.MINI_PROGRAM)),
              global.Win.show())
            : a.fromAction
              ? (g.dispatch(h.selectDevType(i.DEV_TYPE.MINI_PROGRAM)),
                global.Win.show())
              : global.contentDocument.hidden &&
                (0 === m.size
                  ? f.quit()
                  : setTimeout(() => {
                      0 === n.size && global.contentDocument.hidden && f.quit()
                    }, 5e3)))
    },
    s = () => {
      l &&
        l.postMessage({
          type: e.EVENT_SVR_WINDOW_CLI_PORT_UPDATE,
          cliPort: global.cliPort
        })
    }
  module.exports = {
    init: () => {
      ;(l = new BroadcastChannel(e.BROADCAST_CHANNEL_NAME)),
        (l.onmessage = b),
        o.on(e.EVENT_DEV_WINDOW_OPENED, () => {
          global.Win.hide()
        })
    },
    once: a =>
      new Promise(b => {
        o.once(a, b)
      }),
    onceWindowOpen: ({ id: a, projectid: b } = {}) =>
      new Promise(c => {
        a || (a = b), o.once(`${e.EVENT_DEV_WINDOW_OPENED}-${a}`, c)
      }),
    onceCliPortUpdate: ({ id: a, projectid: b } = {}) =>
      new Promise(c => {
        a || (a = b),
          o.once(`${e.EVENT_DEV_WINDOW_CLI_PORT_UPDATE}-${a}`, (a, b, d) => {
            c(d)
          })
      }),
    pendingOpenWindows: m,
    clientWindows: n,
    serverSyncEvents: o,
    closeDevWindow: a => {
      return (
        !!l && (l.postMessage({ type: e.COMMAND_DEV_WINDOW_CLOSE, id: a }), !0)
      )
    },
    notifyCliPortUpdate: s,
    getClientIdByProjectId: function(a) {
      for (const [b, c] of n) if (c && c.projectid === a) return b
      return null
    }
  }
})(require('lazyload'), require)
