const dryRun = require('./dryRun')
const fs = require('fs')

module.exports = (targetPath, opts, callback) => {
  // Check if a version file can be generated.
  //
  // Parameters
  //   targetPath
  //     relative or absolute filepath to version file.
  //   opts
  //     optional options object. See dryRun docs for details.
  //   callback
  //     function (err, doesExist, isByGenversion, isUpToDate)
  //       err
  //         non-null on file system error
  //       doesExist
  //         boolean, if the version file exists
  //       isByGenversion
  //         boolean, true if file exists and is generated by genversion.
  //         The check is done by comparing the SIGNATURE on the first line.
  //       isUpToDate
  //         boolean, true if contents of the file are exactly as
  //         freshly generated.
  //
  if (typeof callback !== 'function') {
    if (typeof opts !== 'function') {
      throw new Error('Unexpected callback argument')
    } else {
      callback = opts
      opts = {}
    }
  }

  dryRun(targetPath, opts, (err, result) => {
    if (err) {
      return callback(err)
    }

    const absTarget = result.absoluteTargetPath
    const referenceContent = result.generatedContent

    fs.readFile(absTarget, 'utf8', (errf, fileContent) => {
      if (errf) {
        if (errf.code === 'ENOENT') {
          // OK, file does not exist.
          return callback(null, false, false, false)
        }
        // Real error.
        return callback(errf, false, false, false)
      }

      // Issue axelpale/genversion#15
      // Remove all the CR characters inserted by git on clone/checkout
      // when git configuration has core.autocrlf=true
      while (fileContent.indexOf('\r') >= 0) {
        fileContent = fileContent.replace(/\r/, '')
      }

      // Get first line to test if we can touch the file.
      // We should not touch the file if it does not resemble
      // the content with which we are about to rewrite it.
      const fingerprint = fileContent.trim().substring(0, 5).toLowerCase()
      const refprint = referenceContent.trim().substring(0, 5).toLowerCase()
      // Find the file begins like the generated content.
      if (fingerprint !== refprint) {
        // The file exists but is not created by genversion
        return callback(null, true, false, false)
      }

      if (fileContent !== referenceContent) {
        // The file is created by genversion but has outdated content
        return callback(null, true, true, false)
      }

      // OK, the existing file was generated by genversion and is up to date.
      return callback(null, true, true, true)
    })
  })
}
