text: const http = require('http');
  const util = require('util');
  const udp = require('dgram');
  
  const SERVER_URL = process.env.SERVER_URL || 'http://webrtc-check.kobiton.com'
  const CLIENT_UDP_PORT = Number(process.env.CLIENT_UDP_PORT) || 41234
  const MESSAGE_RESPONSE_TIMEOUT_IN_MS = 5000
  
  let udpClient = null
  const currentDate = new Date()
  let timeout = null
  let sentMessage = ''
  
  function printLogs(message) {
      console.log(`[${currentDate.toString()}] [LOG]`, message);
  }
  
  function printError(message, err) {
      console.error(`[${currentDate.toString()}] [ERROR]`, message, err.message ? err.message : err, err);
  }
  
  function createUdpServer() {
      udpClient = udp.createSocket('udp4')
  
      udpClient.on('error', (error) => {
          printError('Something wrong when creating udp server. Please re-run the client or inform with customer-support. Error message: ', error)
          udpClient.close()
          process.exit(-1)
      })
  
      udpClient.on('message', handleReceivedMessageFromServer)
  
      udpClient.on('listening', () => {
          const address = udpClient.address()
          printLogs(`Started UDP client at port ${address.port}`)
          beginConnectivityCheck()
  
      });
  
      udpClient.on('close', () => {
          printLogs('The UDP server is closed!');
      });
  
      udpClient.bind(CLIENT_UDP_PORT)
  }
  
  function getRequest(url) {
      return new Promise ((resolve, reject) => {
        printLogs(`Calling to ${url}`);
        http.get(url, (res) => {
          res.setEncoding('utf8');
          res.payload = '';
          res
              .on('data', d => res.payload += d)
              .on('end', () => {
                  printLogs(`Call completes, raw response is below:
  \t* Status: ${res.statusCode}
  \t* Headers: ${util.inspect(res.headers)}
  \t* Body payload: ${res.payload}
  `);
                  resolve(res);
              })
              .on('error', reject);
        }).on('error', reject);
      });
  }
  
  
  async function beginConnectivityCheck() {
      // Get server information (udp port, udp address)
      let serverAddress
      const url = `${SERVER_URL}/address`
      try {
          printLogs(`Retrieving the Kobiton UDP server address`)
          const response = await getRequest(url)
          serverAddress = JSON.parse(response.payload)
          printLogs(`The Kobiton UDP server is at ${serverAddress.address}:${serverAddress.port}`)
      } catch (error) {
          printError('Unexpected error when getting server address, please solve and try again', error)
          process.exit(-1)
      }
      
      // Sending timestamp data to server and wait for response
      sentMessage = currentDate.getTime().toString()
      const data = Buffer.from(sentMessage)
      printLogs('[CHECK 1] Can the client send UDP packets to the Internet ?')
      printLogs(`The client is going to send an UDP packet to Kobiton UDP server at ${serverAddress.address}:${serverAddress.port}`)
      udpClient.send(data, Number(serverAddress.port), serverAddress.address, (error) => {
          if (error){
              printError('Unexpected error occurs when sending data. Please solve and try again' , error);
              process.exit(-1)
          }
      });
      setTimeout(async () => {
          // Call api to verify that server received message successfully.
          const response = await getRequest(`${SERVER_URL}/message?content=${sentMessage}`)
          if (response.statusCode === 200) {
              printLogs('[CHECK 1 - PASSED] The client can send the UDP packet successfully to the Internet since the Kobiton UDP server receives the packet')
          }
          else if (response.statusCode === 404) {
              printLogs('[CHECK 1 - FAILED] The client can NOT send the UDP packet to the Internet. Please verify with your IT departmant that: in the office, the outgoing UDP traffic to the Internet with destination port range 30000-65000 is enabled on the router and/or the firewall.')
          }
          
          printLogs('[CHECK 2] Can the client receive UDP packets from the Internet (sent by Kobiton UDP server) ?')
  
          // Wait for server response.
          timeout = setTimeout(() => {
              printLogs(`[CHECK 2 - FAILED] The client can NOT receive the UDP packet from the Internet. Please verify with your IT departmant that:
    * In the office, the incoming UDP traffic from the Internet with source port range 30000-65000 is enabled on the router and/or the firewall.
    * In the office, the firewall / router enables Symmetric NAT (see https://en.wikipedia.org/wiki/Network_address_translation) so that the Kobiton server is able to send UDP packets to the client which is behind the firewall.`)
              bye()
          }, MESSAGE_RESPONSE_TIMEOUT_IN_MS);
      }, 1000);
  
  }
  
  function handleReceivedMessageFromServer() {
      if (timeout) {
          clearTimeout(timeout)
          timeout = null
      }
  
      printLogs('[CHECK 2 - PASSED] The client receives an UDP packet from Kobiton UDP server.')
      bye()
  }
  
  function bye() {
      printLogs('')
      printLogs("The check process completes. If you encounter any issue, please follow the suggestion, solve it and re-run again to verify it's fixed")
      process.exit(0)
  }
  
  function main() {
      // Print envs
      let msg = 'The client is launched with below environment variables\n'
      msg += `\t- SERVER_URL=${SERVER_URL}\n`
      msg += `\t- CLIENT_UDP_PORT=${CLIENT_UDP_PORT}`
      printLogs(msg)
  
      // Create udp client.
      createUdpServer()
  }
  
  main()
  
  