const {extractEyesDataFromHeaders, generateEgTunnelError} = require('../../utils')

module.exports = {handler, extractErrorLogFields}

const CREATE_TUNNEL_ACTION_NAME = 'create-tunnel'

async function handler(request, reply) {
  const {apiKey, eyesServerUrl} = extractEyesDataFromHeaders(request)
  const environment = request.body ? request.body.environment : 'LATEST'

  let tunnelId, error
  let config

  // TODO: create function for performance
  try {
    request.timer.reset() // reset timer before starting tunnel

    const {tunnelProxy, frpcConf} = await this.egTunnelManager.createTunnel({
      apiKey,
      eyesServerUrl,
      environment,
    })
    tunnelId = tunnelProxy.id
    config = frpcConf
  } catch (e) {
    error = e
  } finally {
    request.performance.startTunnelRequest = request.timer.getTime()
  }

  if (error) {
    throw error
  }

  try {
    request.timer.reset() // reset timer before starting tunnel
    await this.tunnelProcessManager.start({tunnelId, config})
  } catch (e) {
    error = generateEgTunnelError(e, 500)
  } finally {
    request.performance.startTunnelProcess = request.timer.getTime()
  }

  if (error) {
    // release tunnel proxy
    await this.egTunnelManager
      .deleteTunnel({
        tunnelId,
        apiKey,
        eyesServerUrl,
        reason: 'FRPC_STARTUP_FAILURE',
      })
      .catch((e) => {
        error.deleteTunnelError = e.message
      })

    throw error
  }

  this.logger.info({
    action: CREATE_TUNNEL_ACTION_NAME,
    tunnelEnvironment: environment,
    tunnelId,
    success: true,
    performance: request.performance,
  })

  reply.code(201).header('Content-Type', 'application/json').send(JSON.stringify(tunnelId))
}

function extractErrorLogFields(error, request) {
  const {performance} = request
  const tunnelEnvironment = request.body ? request.body.environment : undefined

  return {
    action: CREATE_TUNNEL_ACTION_NAME,
    tunnelEnvironment,
    success: false,
    error,
    performance,
  }
}
