/*
 * This job renders `data` using nunjucks template `type`
 */

const nunjucks = require('nunjucks')
const fs = require('fs')
const dateFilter = require('nunjucks-date-filter')
const util = require('util')
const url = require('url')

const config = require('./config')

console.log(`watch: ${config.watch}`)
const env = new nunjucks.Environment(
  new nunjucks.FileSystemLoader(`${config.themeDir}/templates`, {
    watch: config.watch,
  }),
)

env.addFilter('date', dateFilter)

env.addFilter('paginationList', (page, count) => {
  let curPage = page
  const pages = []
  pages.push(curPage)
  for (let i = 0; i < count; i += 1) {
    curPage = curPage.metadata.prevpage
    if (curPage === undefined) break
    pages.unshift(curPage)
  }

  curPage = page
  for (let i = 0; i < count; i += 1) {
    curPage = curPage.metadata.nextpage
    if (curPage === undefined) break
    pages.push(curPage)
  }
  return pages
})

env.addFilter('inspect', obj => util.inspect(obj))

env.addFilter('log', obj => console.log(obj))

env.addFilter('relURL', (filename, dir_) => {
  let dir = dir_
  if (filename.substr(0, 1) === '/' || filename.match('://')) return filename
  if (dir.substr(0, 1) !== '/') dir = `/${dir}`
  if (filename.match(/\/$/)) return dir + filename
  if (dir.match(/\/$/)) return dir + filename
  return `${dir}/${filename}`
})

env.addFilter('absURL', (rel, base) => url.resolve(base, rel))

let formats = {}

module.exports = (data, type_) =>
  new Promise((resolve, reject) => {
    if (formats[type_]) resolve(formats[type_])
    else {
      fs.readdir(`${config.themeDir}/templates`, (err, files_) => {
        if (err) {
          console.log(config)
          reject(
            new Error(`Error listing files in ${config.themeDir}/templates`),
          )
          return
        }

        const files = files_.filter(file => file.match(`${type_}..*.nunj`))

        const filteredFiles = []
        let todo = 0
        files.forEach(file => {
          fs.stat(`${config.themeDir}/templates/${file}`, (err2, stat) => {
            if (err2)
              reject(
                new Error(`Error stating ${config.themeDir}/templates${file}`),
              )
            if (stat.isFile()) filteredFiles.push(file)
            todo -= 1
            if (todo <= 0) {
              formats[type_] = filteredFiles
              resolve(filteredFiles)
            }
          })
          todo += 1
        })
      })
    }
  })
    .then(filelist => {
      const promises = []
      filelist.forEach(file => {
        const type = file.replace(/^.*\.([a-z]+)\.nunj/, '$1')
        promises.push(
          new Promise((resolve, reject) => {
            env.getTemplate(file, (err, tmpl) => {
              if (err)
                reject(new Error(`Failed to load template ${type}.html.nunj`))
              resolve({ tmpl, type, file })
            })
          }),
        )
      })
      return Promise.all(promises)
    })
    .then(tmpls => {
      const promises = []
      tmpls.forEach(o => {
        promises.push(
          new Promise((resolve, reject) => {
            const param = {
              ...data,
              config: {
                ...data.config,
                baseurl: config ? config.options.baseurl : '',
              },
            }
            o.tmpl.render(param, (err, val) => {
              if (err) {
                // reject(new Error('Error rendering template '+o.file));
                reject(err)
              }
              resolve({ content: val, type: o.type })
            })
          }),
        )
      })
      return Promise.all(promises)
    })

module.exports.reset = () => {
  formats = {}
}