const fs = require('fs')
const https = require('https')
const argv = require('minimist')(process.argv.slice(2))

require('./environment-helper')
const { loadRoutes } = require('./routes')
const logger = require('./logger')
const poller = require('./poller')
const settingsLoader = require('./new-settings-loader')
const configManager = require('./new-config-manager')
const complianceTriggers = require('./compliance-triggers')
const ofac = require('./ofac/index')
const ofacUpdate = require('./ofac/update')
const operator = require('./operator')

const KEY_PATH = process.env.KEY_PATH
const CERT_PATH = process.env.CERT_PATH
const CA_PATH = process.env.CA_PATH

const version = require('../package.json').version
logger.info('Version: %s', version)

function run() {
  return new Promise(resolve => {
    let count = 0
    let handler

    const errorHandler = err => {
      count += 1
      logger.error(err)
      logger.error('[%d] Retrying in 10s...', count)
    }

    const runner = () => {
      settingsLoader
        .loadLatest()
        .then(settings => {
          clearInterval(handler)
          return loadSanctions(settings).then(startServer).then(resolve)
        })
        .catch(errorHandler)
    }

    handler = setInterval(runner, 10000)
    runner()
  })
}

function loadSanctions(settings) {
  return Promise.resolve().then(() => {
    const triggers = configManager.getTriggers(settings.config)
    const hasSanctions = complianceTriggers.hasSanctions(triggers)

    if (!hasSanctions) return

    logger.info('Loading sanctions DB...')
    return ofacUpdate
      .update()
      .then(() => logger.info('Sanctions DB updated'))
      .then(ofac.load)
      .then(() => logger.info('Sanctions DB loaded'))
  })
}

async function startServer() {
  const app = await loadRoutes()

  poller.setup()

  const httpsServerOptions = {
    key: fs.readFileSync(KEY_PATH),
    cert: fs.readFileSync(CERT_PATH),
    ca: fs.readFileSync(CA_PATH),
    requestCert: true,
    rejectUnauthorized: false,
  }

  const server = https.createServer(httpsServerOptions, app)

  const port = argv.port || 3000

  await operator.getOperatorId('middleware').catch(logger.error)
  await new Promise(resolve => server.listen({ port }, resolve))
  logger.info(`lamassu-server listening on port ${port}`)
}

module.exports = { run }
