const Koa = require('koa')
const compose = require('koa-compose') // 组合中间件，简化写法
const http = require('http')
const { clientPort } = require('./config')
const { httpPort } = require('./config')
const middlewares = require('./middlewares')
const wsMonitorOsInfo = require('./socket/monitor')
const wsTerminal = require('./socket/terminal')
const wsSftp = require('./socket/sftp')
const wsHostStatus = require('./socket/host-status')
const wsClientInfo = require('./socket/clients')
const { throwError } = require('./utils')

const httpServer = () => {
  const app = new Koa()
  const server = http.createServer(app.callback())
  serverHandler(app, server)
  // ws一直报跨域的错误：参照官方文档使用createServer API创建服务
  server.listen(httpPort, () => {
    consola.success(`Server(http) is running on: http://localhost:${ httpPort }`)
  })
}

const clientHttpServer = () => {
  const app = new Koa()
  const server = http.createServer(app.callback())
  wsMonitorOsInfo(server) // 监控本机信息
  server.listen(clientPort, () => {
    consola.success(`Client(http) is running on: http://localhost:${ clientPort }`)
  })
}

// 服务
function serverHandler(app, server) {
  app.proxy = true // 用于nginx反代时获取真实客户端ip
  wsTerminal(server) // 终端
  wsSftp(server) // sftp
  wsHostStatus(server) // 终端侧边栏host信息
  wsClientInfo(server) // 客户端信息
  app.context.throwError = throwError // 常用方法挂载全局ctx上
  app.use(compose(middlewares))
  // 捕获error.js模块抛出的服务错误
  app.on('error', (err, ctx) => {
    ctx.status = 500
    ctx.body = {
      status: ctx.status,
      message: `Program Error：${ err.message }`
    }
  })
}

module.exports = {
  httpServer,
  clientHttpServer
}