/* ----------------------------------------------------------------------------

 Question Server
 GitLab: <https://gitlab.com/MrFry/mrfrys-node-server>

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program. If not, see <https://www.gnu.org/licenses/>.

 ------------------------------------------------------------------------- */

const startHTTPS = true
const port = 8080
const httpsport = 5001

const express = require('express')
const vhost = require('vhost')
const logger = require('./utils/logger.js')
const utils = require('./utils/utils.js')
const http = require('http')
const https = require('https')
const cors = require('cors')

const extraModulesFile = './extraModules.json'
const modulesFile = './modules.json'

const loggableKeywords = [
  'user.js'
]
let modules = JSON.parse(utils.ReadFile(modulesFile))

let logLevel = parseInt(GetParams()[0])
if (isNaN(logLevel)) {
  logLevel = 0
}
logger.Log('Loglevel is: ' + logLevel)
logger.Load(logLevel) // TODO: debug level in enviromet variable / param

function GetParams () {
  return process.argv.splice(2)
}

try {
  if (utils.FileExists(extraModulesFile)) {
    const extraModules = JSON.parse(utils.ReadFile(extraModulesFile))
    modules = {
      ...extraModules,
      ...modules
    }
  }
} catch (e) {
  logger.Log('Failed to read extra modules file')
  console.log(e)
}

const app = express()
app.use(cors())

app.use(function (req, res, next) {
  res.on('finish', function () {
    if (req.url.includes('_next/static')) {
      return
    }
    let ip = req.headers['cf-connecting-ip'] || req.connection.remoteAddress
    logger.LogReq(req, true, res.statusCode)
    let toLog = loggableKeywords.some((x) => {
      return req.url.includes(x)
    })
    if (toLog) { logger.LogReq(req) }
    if (res.statusCode !== 404) { logger.LogStat(req.url, ip) }
  })
  next()
})

Object.keys(modules).forEach(function (k, i) {
  let x = modules[k]
  try {
    let mod = require(x.path)
    if (mod.setup) {
      mod.setup({
        url: 'http://' + x.urls[0] // TODO http https or neither
      })
    }
    x.app = mod.app
    x.urls.forEach((url) => {
      app.use(vhost(url, x.app))
    })
  } catch (e) {
    console.log(e)
  }
})

const locLogFile = './stats/logs'
const allLogFile = '/nlogs/log'

// https://certbot.eff.org/
const privkeyFile = '/etc/letsencrypt/live/frylabs.net/privkey.pem'
const fullchainFile = '/etc/letsencrypt/live/frylabs.net/fullchain.pem'
const chainFile = '/etc/letsencrypt/live/frylabs.net/chain.pem'

var certsLoaded = false
if (startHTTPS && utils.FileExists(privkeyFile) && utils.FileExists(fullchainFile) && utils.FileExists(
  chainFile)) {
  try {
    const key = utils.ReadFile(privkeyFile)
    const cert = utils.ReadFile(fullchainFile)
    const ca = utils.ReadFile(chainFile)
    var certs = {
      key: key,
      cert: cert,
      ca: ca
    }
    certsLoaded = true
  } catch (e) {
    logger.Log('Error loading cert files!', logger.GetColor('redbg'))
    console.log(e)
  }
}

function setLogTimer () {
  const d = new Date()
  const h = new Date(
    d.getFullYear(),
    d.getMonth(),
    d.getDate() + 1,
    0,
    0,
    0,
    0
  )
  const e = h - d

  if (e > 100) {
    setTimeout(setLogTimer, e)
  } else {
    logger.Log('Log timer malfunction :/')
  }

  const line = '-------------------------------------------------------------------------------'

  logger.Log(line)
  utils.AppendToFile(line, locLogFile)
  utils.AppendToFile(line, allLogFile)
}

setLogTimer()

logger.Log('Node version: ' + process.version)
logger.Log('Listening on port: ' + port)

const httpServer = http.createServer(app)
httpServer.listen(port)
if (certsLoaded) {
  const httpsServer = https.createServer(certs, app)
  httpsServer.listen(httpsport)
  logger.Log('Listening on port: ' + httpsport + ' (https)')
} else {
  logger.Log('Https not avaible')
}

// app.listen(port)