const fs = require('fs')
const path = require('path')
const { createConverter } = require('convert-svg-to-png')
const terminalOverwrite = require('terminal-overwrite')

// Fix memoryleak warning
const maxConvertProcesses = 1
process.setMaxListeners(maxConvertProcesses + 1)

const appPaths = () => {
  const fileDir = path.dirname(require.main.filename).split('/')
  // Remove current bin directory
  fileDir.pop()
  const appDir = fileDir.join('/')

  return {
    basePath: fileDir,
    appPath: appDir,
    iconPath: appDir + '/src/drivers/webextension/images/icons',
    convertPath: appDir + '/src/drivers/webextension/images/icons/converted',
  }
}

/**
 * Copy files from source to destination.
 * @param source
 * @param destination
 */
function copyFiles(source, destination) {
  // File destination will be created or overwritten by default.
  fs.copyFileSync(source, destination)
  // console.log(`${source} -> ${destination}`)
}

/**
 * Get extension of image file.
 * @returns {string}
 */
function getFileExtension(filePath) {
  return path.extname(filePath)
}

/**
 * Get base name of image file.
 * @returns {string}
 */
function getFileName(filePath) {
  return path.basename(filePath, getFileExtension(filePath))
}

function getConvertFileName(filePath) {
  const name = getFileName(filePath)
  return `${appPaths().convertPath}/${name}.png`
}

/**
 * Check if converted image exists
 * @returns {boolean}
 */
function checkFileExists(imagePath) {
  const fileExists = fs.existsSync(imagePath)
  return fileExists
}

/**
 * Check if path is a file
 * @param {*} filePath
 * @returns
 */
function checkIfFile(filePath) {
  return fs.statSync(filePath).isFile()
}

function dateModified(file) {
  return fs.statSync(file).mtime
}

function dateDiff(file) {
  const now = new Date().getTime()
  const then = dateModified(file).getTime()
  return Math.round(Math.abs(((then - now) / 1000) * 60 * 60 * 24))
}

;(async () => {
  // Main script
  const files = fs.readdirSync(appPaths().iconPath)
  const totalFiles = files.length
  const batchNum = Math.ceil(totalFiles / maxConvertProcesses)
  let batchCount = 1

  const converter = createConverter()

  do {
    const percentComplete = `${
      100 - Math.round((100 / totalFiles) * files.length)
    }%`
    terminalOverwrite(
      `Processing Batch: ${batchCount} of ${batchNum} (${percentComplete})`
    )

    await Promise.all(
      files.splice(0, maxConvertProcesses).map(async (fileName) => {
        const path = `${appPaths().iconPath}/${fileName}`
        const outputFilePath = getConvertFileName(fileName)
        const ext = getFileExtension(path)

        if (ext === '.svg') {
          // Check if converted file exists.
          if (checkFileExists(outputFilePath)) {
            // Skip if destination file exists and source file hasn't changed in
            // 30 days or destination file was created in the last day
            const fileAgeA = dateDiff(path)
            const fileAgeB = dateDiff(outputFilePath)

            if (fileAgeA > 30 || fileAgeB < 1) {
              return
            }
          }

          // Convert and copy file.
          for (let attempt = 1; attempt <= 3; attempt++) {
            try {
              await converter
                .convertFile(path, {
                  height: 32,
                  width: 32,
                  outputFilePath,
                })
                .catch((error) => {
                  throw new Error(`${error} (${fileName})`)
                })

              break
            } catch (error) {
              if (attempt >= 3) {
                throw error
              } else {
                // eslint-disable-next-line no-console
                console.error(`${error.message || error} (attempt ${attempt})`)

                await new Promise((resolve) =>
                  setTimeout(resolve, 500 * attempt)
                )
              }
            }
          }
        } else if (this.ext === '.png') {
          // If PNG, just copy the file as-is.
          // eslint-disable-next-line no-lonely-if
          if (checkIfFile(this.path)) {
            copyFiles(this.path, this.convertPath)
          }
        }
      })
    )

    batchCount++
  } while (files.length)

  await converter.destroy()

  // eslint-disable-next-line no-console
  console.log(`Converted ${totalFiles.toLocaleString()} files.`)
})()

/**

cd  ; cp *.svg converted ; cd converted ; convert-svg-to-png *.svg --width 32 --height 32 ; rm *.svg
(async() => {
  const inputFilePath = '/path/to/my-image.svg';
  const outputFilePath = await convertFile(inputFilePath);

  console.log(outputFilePath);
  //=> "/path/to/my-image.png"
})();
*/