/**
 * Sent E-Mail in the same way as mail scheduler dose
 *
 * Usage from a command line:

cd /opt/unitybase/product/my-product
mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env
# or
strace -f -e trace=network mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env

 * @author pavel.mash
 * @module mail
 * @memberOf module:@unitybase/ubcli
 */

// const fs = require('fs')
// const path = require('path')
const cmdLineOpt = require('@unitybase/base').options
const argv = require('@unitybase/base').argv

module.exports = function mailSend (options) {
  if (!options) {
    const opts = cmdLineOpt.describe('mail', `Send E-Mail using mailer from server config.
Example for tracing network activity:
cd /opt/unitybase/product/my-product
strace -f -e trace=network ubcli mail --mail-rcpt "my@test.com" -env /var/opt/unitybase/my-app/ubConfig.env`,
    'ubcli'
    )
      .add({ short: 'cfg', long: 'cfg', param: 'serverConfig', defaultValue: 'ubConfig.json', help: 'Server config' })
      .add({ short: '-to', long: '-to', param: 'to', help: 'To: mail address' })
      .add({ short: '-cc', long: '-cc', param: 'cc', defaultValue: '', help: 'Cc: mail address' })
      .add({ short: '-bcc', long: '-bcc', param: 'bcc', defaultValue: '', help: 'Bcc: mail address' })
      .add({ short: '-reply-to', long: '-reply-to', param: 'replyTo', defaultValue: '', help: 'Reply-To: mail address' })
      // .add({ short: '-upload-file', long: '-mail-rcpt', param: 'uploadFile', defaultValue: '', help: 'File to upload' })
      .add({ short: '-body', long: '-body', param: 'body', defaultValue: 'UnityBase mailer test', help: 'E-Mail body' })
    options = opts.parseVerbose({}, true)
    if (!options) return
  }
  console.log(options)
  const serverConfig = argv.getServerConfiguration()
  const mailerParams = serverConfig.application.customSettings.mailerConfig
  if (!mailerParams) {
    console.error('ubConfig.json "application.customSettings.mailerConfig" section is missed')
    return
  }
  if (!mailerParams.targetHost) {
    console.error('ubConfig.json "application.customSettings.mailerConfig.targetHost" is not configured')
    return
  }
  const mailerCfg = {
    host: mailerParams.targetHost,
    port: mailerParams.targetPort || '25',
    user: mailerParams.user || '',
    password: mailerParams.password || '',
    tls: Boolean(mailerParams.autoTLS),
    fullSSL: Boolean(mailerParams.fullSSL),
    auth: mailerParams.auth || false,
    deferLogin: true
  }
  console.debug('Mailer config:\n' + JSON.stringify(mailerCfg, null, ' '))
  let UBMail
  try {
    UBMail = require('@unitybase/mailer')
  } catch (e) {
    console.error('@unitybase/mailer package is not installed for application')
    throw e
  }
  if (mailerParams.oauthProvider) {
    console.info(`Try to obtain XOAUTH2 token using customSettings.openIDConnect.${mailerParams.oauthProvider} configuration`)
    const oidcCfg = serverConfig.application.customSettings.openIDConnect
    if (!oidcCfg) {
      throw new Error('ubConfig.application.customSettings.openIDConnect section is empty')
    }
    const provCfg = oidcCfg[mailerParams.oauthProvider]
    if (!provCfg) {
      throw new Error(`ubConfig.application.customSettings.openIDConnect.${mailerParams.oauthProvider} section is empty`)
    }
    console.info('Token provider config is ', provCfg)
    const xoauth2Token = openIDGetCCToken(provCfg, provCfg.emailTokenScope)
    mailerCfg.OAuth2Token = xoauth2Token
  }
  console.time('SMTP_session')
  const mailSender = new UBMail.TubMailSender(mailerCfg)
  mailSender.login()

  const mailObj = {
    fromAddr: mailerParams.fromAddr || ('no-reply@' + mailerParams.targetHost),
    subject: 'Test email',
    bodyType: UBMail.TubSendMailBodyType.Text,
    body: options['-body'],
    toAddr: [options['-to']]
  }
  if (options['-cc']) {
    mailObj.ccAddr = options['-cc']
  }
  if (options['-bcc']) {
    mailObj.bccAddr = options['-bcc']
  }
  if (options['-reply-to']) {
    mailObj.replyTo = options['-reply-to']
  }
  console.debug('mailSender.sendMail params:', mailObj)
  const fRes = mailSender.sendMail(mailObj)
  console.timeEnd('SMTP_session')
  if (!fRes) {
    console.error('Got answer:', mailSender.lastError)
  } else {
    console.info('Message send')
  }
}

/**
 * @unitybase/openid-connect cannot be used in command line script, so here we emulate getCCToken function locally
 * @param {object} providerConfig
 * @param {string} scope
 * @returns {string}
 */
function openIDGetCCToken (providerConfig, scope) {
  console.time('gotOIDCToken')
  const http = require('http')
  let fields = `grant_type=client_credentials&client_id=${providerConfig.client_id}&client_secret=${providerConfig.client_secret}`
  fields += `&scope=${scope}`
  const tokenRequest = http.request({
    URL: providerConfig.tokenUrl,
    method: 'POST'
  })
  tokenRequest.setHeader('Content-Type', 'application/x-www-form-urlencoded')
  console.debug(`sending POST HTTP request to ${providerConfig.tokenUrl}, body: ${fields}`)
  const tokenResponse = tokenRequest.end(fields)
  if (tokenResponse.statusCode !== 200) {
    const errBody = tokenResponse.read()
    throw new Error(`OpenIDConnect provider return invalid response for tokens request ${tokenResponse.statusCode} body: ${errBody}`)
  }
  const tokenResp = tokenResponse.json()
  const token = tokenResp.access_token
  console.debug('Got access_token:', token)
  console.timeEnd('gotOIDCToken')
  return token
}

module.exports.shortDoc = 'Send E-Mail using mailer config from ubConfig.json'