/**
 *
 *    Copyright (c) 2020 Silicon Labs
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
const { spawn } = require('cross-spawn')
const folderHash = require('folder-hash')
const fs = require('fs')
const fsp = fs.promises
const path = require('path')
const scriptUtil = require('./script-util.js')
const readline = require('readline')
const env = require('../src-electron/util/env')

const spaDir = path.join(__dirname, '../spa')
const backendDir = path.join(__dirname, '../dist')
const spaHashFileName = path.join(spaDir, 'hash.json')
const backendHashFileName = path.join(backendDir, 'hash.json')
process.env.PATH = process.env.PATH + ':./node_modules/.bin/'

const hashOptions = {}

// Utilities shared by scripts.

/**
 * Execute a command and resolve with the context.
 *
 * @param {*} ctx
 * @param {*} cmd
 * @param {*} args
 */
async function executeCmd(ctx, cmd, args) {
  return new Promise((resolve, reject) => {
    console.log(
      env.formatEmojiMessage('🚀', `Executing: ${cmd} ${args.join(' ')}`)
    )
    let c = spawn(cmd, args)
    c.on('exit', (code) => {
      if (code == 0) resolve(ctx)
      else {
        if (code) {
          console.log(
            env.formatEmojiMessage(
              '👎',
              `Program ${cmd} exited with error code: ${code}`
            )
          )
          reject(code)
        } else {
          console.log(
            env.formatEmojiMessage(
              '👎',
              `Program ${cmd} exited with signal code: ${c.signalCode}`
            )
          )
          reject(c.signalCode)
        }
      }
    })
    c.stdout.on('data', (data) => {
      process.stdout.write(data)
    })
    c.stderr.on('data', (data) => {
      process.stderr.write('⇝ ' + data)
    })
    c.on('error', (err) => {
      reject(err)
    })
  })
}

/**
 * Executes a command with arguments and resolves with the stdout.
 *
 * @param {*} onError If there is an error with executable, resolve to this.
 * @param {*} cmd Command to run.
 * @param {*} args Arguments to pass.
 */
async function getStdout(onError, cmd, args) {
  return new Promise((resolve, reject) => {
    console.log(
      env.formatEmojiMessage('🚀', `Executing: ${cmd} ${args.join(' ')}`)
    )
    let c = spawn(cmd, args)
    let str = ''
    c.on('exit', (code) => {
      if (code == 0) resolve(str)
      else {
        console.log(
          env.formatEmojiMessage(
            '👎',
            `Program ${cmd} exited with error code: ${code}`
          )
        )
        reject(code)
      }
    })
    c.stdout.on('data', (data) => {
      str = str.concat(data)
    })
    c.on('error', (err) => {
      resolve(onError)
    })
  })
}

/**
 * Resolves into a context object.
 * Check for context.needsRebuild
 *
 * @returns Promise of SPA rebuilt
 */
async function rebuildSpaIfNeeded() {
  let srcHash = await folderHash.hashElement(
    path.join(__dirname, '../src'),
    hashOptions
  )
  console.log(env.formatEmojiMessage('🔍', `Current src hash: ${srcHash.hash}`))
  let srcSharedHash = await folderHash.hashElement(
    path.join(__dirname, '../src-shared'),
    hashOptions
  )
  console.log(
    env.formatEmojiMessage(
      '🔍',
      `Current src-shared hash: ${srcSharedHash.hash}`
    )
  )
  let ctx = {
    hash: {
      srcHash: srcHash.hash,
      srcSharedHash: srcSharedHash.hash
    }
  }
  return Promise.resolve(ctx)
    .then(
      (ctx) =>
        new Promise((resolve, reject) => {
          fs.readFile(spaHashFileName, (err, data) => {
            let oldHash = null
            if (err) {
              console.log(
                env.formatEmojiMessage(
                  '👎',
                  `Error reading old hash file: ${spaHashFileName}`
                )
              )
              ctx.needsRebuild = true
            } else {
              oldHash = JSON.parse(data)
              console.log(
                env.formatEmojiMessage(
                  '🔍',
                  `Previous src hash: ${oldHash.srcHash}`
                )
              )
              console.log(
                env.formatEmojiMessage(
                  '🔍',
                  `Previous src-shared hash: ${oldHash.srcSharedHash}`
                )
              )
              ctx.needsRebuild =
                oldHash.srcSharedHash != ctx.hash.srcSharedHash ||
                oldHash.srcHash != ctx.hash.srcHash
            }
            if (ctx.needsRebuild) {
              console.log(
                `🐝 Front-end code changed, so we need to rebuild SPA.`
              )
            } else {
              console.log(
                env.formatEmojiMessage(
                  '👍',
                  "There were no changes to front-end code, so we don't have to rebuild the SPA."
                )
              )
            }
            resolve(ctx)
          })
        })
    )
    .then((ctx) => {
      if (ctx.needsRebuild)
        return scriptUtil.executeCmd(ctx, 'npx', ['quasar', 'build'])
      else return Promise.resolve(ctx)
    })
    .then(
      (ctx) =>
        new Promise((resolve, reject) => {
          if (ctx.needsRebuild) {
            console.log(
              env.formatEmojiMessage('✍', 'Writing out new hash file.')
            )
            fs.writeFile(spaHashFileName, JSON.stringify(ctx.hash), (err) => {
              if (err) reject(err)
              else resolve(ctx)
            })
          } else {
            resolve(ctx)
          }
        })
    )
}

/**
 * Rebuilds backend if needed.
 * @returns promise of backend rebuilt
 */
async function rebuildBackendIfNeeded() {
  return scriptUtil
    .executeCmd({}, 'npx', ['tsc', '--build', './tsconfig.json'])
    .then(() =>
      scriptUtil.executeCmd({}, 'npx', [
        'copyfiles',
        './src-electron/**/*.sql',
        './src-electron/icons/*',
        './dist/'
      ])
    )
}

/**
 * Executes:
 *   git log -1 --format="{\"hash\": \"%H\",\"date\": \"%cI\"}"
 * ads the timestamp and saves it into .version.json
 */
async function stampVersion() {
  try {
    let out = await getStdout('{"hash": null,"date": null}', 'git', [
      'log',
      '-1',
      '--format={"hash": "%H","timestamp": %ct}'
    ])
    let version = JSON.parse(out)
    let d = new Date(version.timestamp * 1000) // git gives seconds, Date needs milliseconds
    let result = await setPackageJsonVersion(d, 'real')
    version.date = d
    version.zapVersion = result.version
    let versionFile = path.join(__dirname, '../.version.json')
    console.log(
      env.formatEmojiMessage(
        '🔍',
        `Git commit: ${version.hash} from ${version.date}`
      )
    )
    await fsp.writeFile(versionFile, JSON.stringify(version))
  } catch (err) {
    console.log(`Error retrieving version: ${err}`)
  }
}

/**
 * Sets the version in package.json
 * @param {*} mode 'fake', 'real' or 'print'
 */
async function setPackageJsonVersion(date, mode) {
  if (process.env.ZAP_SKIP_REAL_VERSION != null) {
    // If you set ZAP_SKIP_REAL_VERSION environment variable, then this whole
    // version muddling is turned off.
    return true
  }

  let promise = new Promise((resolve, reject) => {
    let packageJson = path.join(__dirname, '../package.json')
    let output = ''
    let cnt = 0
    let result = {
      wasChanged: false,
      version: null
    }

    const stream = fs.createReadStream(packageJson)
    const rl = readline.createInterface({
      input: stream,
      crlfDelay: Infinity
    })

    rl.on('line', (line) => {
      if (cnt < 10 && line.includes('"version":')) {
        let output
        if (mode == 'real') {
          result.version = `${date.getFullYear()}.${
            date.getMonth() + 1
          }.${date.getDate()}`
          output = `  "version": "${result.version}",`
        } else if (mode == 'fake') {
          result.version = '0.0.0'
          output = `  "version": "${result.version}",`
        } else {
          result.version = line
          output = line
        }

        if (output == line) {
          result.wasChanged = false
        } else {
          line = output
          result.wasChanged = true
        }
        versionPrinted = line
      }
      output = output.concat(line + '\n')
      cnt++
    })

    rl.on('close', () => {
      if (result.wasChanged) {
        fs.writeFileSync(packageJson, output)
      }
      resolve(result)
    })
  })
  return promise
}

/**
 * This method takes a nanosecond duration and prints out
 * decently human readable time out of it.
 *
 * @param {*} nsDifference
 * @returns duration in the form of string
 */
function duration(nsDifference) {
  let diff = Number(nsDifference)
  let out = ''
  if (diff > 1000000000) {
    out += `${Math.floor(diff / 1000000000)}s `
  }
  out += `${Math.round((diff % 1000000000) / 1000000)}ms`
  return out
}

/**
 * Printout of timings at the end of a script.
 * This function also cleans up the package.json
 *
 * @param {*} startTime
 */
async function doneStamp(startTime) {
  let nsDuration = process.hrtime.bigint() - startTime
  console.log(
    env.formatEmojiMessage('😎', `All done: ${duration(nsDuration)}.`)
  )
  return setPackageJsonVersion(null, 'fake')
}

/**
 * Main entry of the program.
 *
 * @param {*} isNode
 * @returns main js file path
 */
function mainPath(isElectron) {
  if (isElectron) {
    return path.join(__dirname, '../dist/src-electron/ui/main-ui.js')
  } else {
    return path.join(__dirname, '../dist/src-electron/main-process/main.js')
  }
}

/**
 * Simple function that reads a JSON file representing an array,
 * and adds an object to it. If file doesn't exist it will create it
 * with an array containing the passed object.
 *
 * @param {*} file
 * @param {*} object
 */
async function addToJsonFile(file, object) {
  let json
  if (fs.existsSync(file)) {
    let data = await fsp.readFile(file)
    json = JSON.parse(data)
  } else {
    json = []
  }
  json.push(object)
  await fsp.writeFile(file, JSON.stringify(json, null, 2))
}

/**
 * Recursive entry
 * @param {*} directory
 * @param {*} depth
 * @param {*} pattern
 * @param {*} collector
 * @returns none
 */
async function doLocate(directory, depth, pattern, collector) {
  if (depth > 50) {
    console.log('WARNING: Recursive depth of 50 exceeded. Aborting.')
    return
  }

  let content = await fsp.readdir(directory)

  for (let f of content.map((x) => path.join(directory, x))) {
    let stat = await fsp.stat(f)
    if (stat.isDirectory()) {
      await doLocate(f, depth + 1, pattern, collector)
    } else if (stat.isFile()) {
      if (f.match(pattern)) {
        collector.push(f)
      }
    }
  }
}
/**
 * Function that recursively finds files under a given directory
 */
async function locateRecursively(rootDir, filePattern) {
  let files = []
  await doLocate(rootDir, 0, filePattern, files)
  return files
}

exports.executeCmd = executeCmd
exports.rebuildSpaIfNeeded = rebuildSpaIfNeeded
exports.rebuildBackendIfNeeded = rebuildBackendIfNeeded
exports.stampVersion = stampVersion
exports.duration = duration
exports.doneStamp = doneStamp
exports.mainPath = mainPath
exports.setPackageJsonVersion = setPackageJsonVersion
exports.addToJsonFile = addToJsonFile
exports.locateRecursively = locateRecursively
