/**
 * @function avgTime
 * @description Returns the average time it takes to close an issue in hours or days.
 * @param {Array} data Array with paths leading to GitLab Issue .json files
 * @param {string} time 'hours' or 'days'
 * @returns {number}
 */

function avgTime(data, time) {
  if (time !== 'hours' && time !== 'days') return Error('avgTime(data, time): time should be "hours" or "days"')
  let avg
  for (const file of data) {
    const issue = require(file.path)
    const openDate = new Date(issue.created_at)
    const closeDate = new Date(issue.closed_at)
    let diff
    if (time === 'days') diff = (closeDate - openDate) / (1000 * 60 * 60 * 24)
    else if (time === 'hours') diff = (closeDate - openDate) / (1000 * 60 * 60)
    avg = (typeof avg === 'undefined')
      ? avg = diff
      : avg += diff
  }
  return (avg / data.length).toFixed(2)
}

/**
 * @function freqUsers
 * @description Returns the top X issue creators.
 * @param {Array} data Array with paths leading to GitLab Issue .json files
 * @param {number} maxUsers Maximum amount of users to return, defaults to 3
 * @returns {Object}
 */

function freqUsers(data, maxUsers) {
  if (typeof maxUsers === 'undefined') maxUsers = 3
  let userCounts = {}
  for (const file of data) {
    const issue = require(file.path)
    if (typeof userCounts[issue.author.username] === 'undefined') userCounts[issue.author.username] = 1
    else userCounts[issue.author.username]++
  }
  const sortedArray = Object.keys(userCounts).sort((a, b) => userCounts[b] - userCounts[a])
  const sortedObject = {}
  for (let i = 0; i < maxUsers; i++) {
    if (typeof sortedArray[i] === 'undefined') break
    sortedObject[sortedArray[i]] = userCounts[sortedArray[i]]
  }
  return sortedObject
}

/**
 * @function labelsAlphabet
 * @description Returns all labels found in alphabetical order with their amount.
 * @param {Array} data Array with paths leading to GitLab Issue .json files
 * @param {boolean} checkNull Boolean whether or not to check if closed_at is null (for currently open issues)
 * @returns {Object}
 */

function labelsAlphabet(data, checkNull) {
  if (typeof checkNull === 'undefined') checkNull = false
  const labels = {}
  for (const file of data) {
    const issue = require(file.path)
    if (checkNull && issue.closed_at !== null) continue
    for (const label of issue.labels) {
      if (typeof labels[label] === 'undefined') labels[label] = 1
      else labels[label]++
    }
  }
  const labelsOrdered = {}
  Object.keys(labels).sort().forEach(label => labelsOrdered[label] = labels[label])
  return labelsOrdered
}

/**
 * @function changedLines
 * @description Returns the number of added, deleted and total lines changed
 * @param {Array} data Array with paths leading to GitLab Commit .json files (with stats)
 * @returns {Object}
 */
function changedLines(data) {
  const stats = {
    added: 0,
    deleted: 0,
    total: 0,
  }
  for (const file of data) {
    const commit = require(file.path)
    stats.added += commit.stats.additions
    stats.deleted += commit.stats.deletions
    stats.total += commit.stats.additions - commit.stats.deletions
  }
  return stats
}

/**
 * @function uniqueContributors
 * @description Returns the names of all contributors
 * @param {Array} data Array with paths leading to GitLab Commit .json files (with stats)
 * @returns {Array}
 */
function uniqueContributors(data) {
  const contributors = []
  for (const file of data) {
    const commit = require(file.path)
    if (!contributors.includes(commit.author_name)) {
      contributors.push(commit.author_name)
    }
  }
  return contributors
}

exports.avgTime = avgTime
exports.freqUsers = freqUsers
exports.labelsAlphabet = labelsAlphabet
exports.changedLines = changedLines
exports.uniqueContributors = uniqueContributors
