const categories = require('../lib/app-categories')
const fs = require('fs')
const path = require('path')
const yaml = require('yamljs')
const slugs = fs.readdirSync(path.join(__dirname, '../apps'))
  .filter(filename => {
    return fs.statSync(path.join(__dirname, `../apps/${filename}`)).isDirectory()
  })

const keywordMappings = {
  'book': 'Books',
  'developer': 'Developer Tools',
  'developers': 'Developer Tools',
  'development': 'Developer Tools',
  'ebook': 'Books',
  'facebook': 'Social Networking',
  'graphics': 'Photo & Video',
  'photo': 'Photo & Video',
  'photo-manager': 'Photo & Video',
  'photos': 'Photo & Video',
  'photoshop': 'Photo & Video',
  'video': 'Photo & Video',
  'video editing': 'Photo & Video',
  'video editor': 'Photo & Video',
  'video viewer': 'Photo & Video',
  'videos': 'Photo & Video',
  'editor': 'Productivity',
  'menubar': 'Utilities',
  'note': 'Productivity',
  'notes': 'Productivity',
  'utility': 'Utilities',
  'util': 'Utilities',
  'launcher': 'Utilities',
  'js': 'Developer Tools',
  'debug': 'Developer Tools',
  'browser': 'Productivity',
  'web browser': 'Productivity',
  'database': 'Developer Tools',
  'excel': 'Productivity',
  'design': 'Productivity',
  'ide': 'Developer Tools',
  'search': 'Utilities',
  'messaging': 'Social Networking',
  'chat': 'Social Networking',
  'collaboration': 'Social Networking',
  'screenshot': 'Utilities',
  'api': 'Developer Tools',
  'clipboard': 'Utilities',
  'bitcoin': 'Finance',
  'markdown': 'Productivity',
  'notebook': 'Productivity',
  'youtube': 'Photo & Video',
  'testing': 'Developer Tools',
  'prototyping': 'Developer Tools',
  'pdf': 'Productivity',
  'aggregator': 'Utilities',
  'npm': 'Developer Tools',
  'mongodb': 'Developer Tools',
  'comic': 'Books',
  'comics': 'Books',
  'manager': 'Utilities',
  'sql': 'Developer Tools',
  'translation': 'Utilities',
  'google': 'Productivity',
  'email': 'Productivity',
  'twitter': 'Social Networking',
  'code': 'Developer Tools',
  '3d printing': 'Utilities',
  'children': 'Education',
  'encryption': 'Utilities',
  'webinar': 'Business',
  'devdocs': 'Developer Tools',
  'docker': 'Developer Tools',
  'music client': 'Music',
  'music player': 'Music',
  'podcasts': 'News',
  'utorrent': 'Utilities',
  'torrent': 'Utilities',
  'periodic-table': 'Utilities',
  'art': 'Photo & Video',
  'hardware': 'Utilities',
  'webgl': 'Photo & Video',
  'svg': 'Photo & Video',
  'collections': 'Productivity',
  'hosts': 'Developer Tools',
  'bookmarking': 'Productivity',
  'blog editor': 'Productivity',
  'media': 'Photo & Video',
  'kanban': 'Productivity',
  'regex': 'Developer Tools',
  'data': 'Developer Tools',
  'onenote': 'Productivity',
  'photography': 'Photo & Video',
  'medicine': 'Medical',
  'productivity tool': 'Productivity',
  'system': 'Utilities',
  'tournament': 'Games',
  'webrtc': 'Social Networking',
  'build': 'Developer Tools',
  'trading': 'Finance',
  'images': 'Photo & Video',
  'time': 'Productivity',
  'gif': 'Photo & Video',
  'nodejs': 'Developer Tools',
  'github': 'Developer Tools'
}

const keywordCounts = {}
const usedCategories = {}

function determineCategory (app, yamlPath) {
  let guessingKeywords = false
  let updateYaml = false
  let matched = false
  let matchedKeyword

  if (!app.keywords) {
    app.keywords = app.description.split(' ')
    guessingKeywords = true
  }

  app.keywords.some((keyword, index) => {
    matched = categories.find((category) => {
      if (keyword.toLowerCase() === category.toLowerCase()) {
        matchedKeyword = keyword
        return true
      }
    })
    return matched
  })
  if (!matched) {
    // look in mappings
    app.keywords.some((keyword, index) => {
      let lowerKeyword = keyword.toLowerCase()
      if (keywordMappings[lowerKeyword]) {
        matched = keywordMappings[lowerKeyword]
        matchedKeyword = keyword
        return true
      } else {
        return false
      }
    })
  }

  if (matched) {
    app.category = matched
    updateYaml = true
    if (!usedCategories[matched]) {
      usedCategories[matched] = 1
    } else {
      usedCategories[matched]++
    }
  }
  if (!updateYaml) {
    app.keywords.forEach((keyword) => {
      let lowerKeyword = keyword.toLowerCase()
      if (keywordCounts[lowerKeyword]) {
        keywordCounts[lowerKeyword]++
      } else {
        keywordCounts[lowerKeyword] = 1
      }
    })
  }

  if (updateYaml) {
    if (guessingKeywords) {
      app.keywords = [
        matchedKeyword
      ]
      console.log(`SUCCESS ${app.name} has been given ${app.category} by guessing keyword: ${matchedKeyword}`)
    } else {
      console.log(`SUCCESS ${app.name} has been given ${app.category} by using keyword: ${matchedKeyword}`)
    }
    saveYaml(app, yamlPath)
  } else {
    if (guessingKeywords) {
      console.log(`${app.name} does not have keywords, its description is: ${app.description}.`)
    } else {
      console.log(`Could not find category for ${app.name}, keywords are: ${app.keywords.join(',')}, description is: ${app.description}`)
    }
  }
}

function removeElectron (app, yamlPath) {
  if (app.keywords) {
    let electronIndex = app.keywords.findIndex((keyword) => {
      return keyword.toLowerCase() === 'electron'
    })
    if (electronIndex > -1) {
      app.keywords.splice(electronIndex, 1)
      saveYaml(app, yamlPath)
    }
  }
}

function saveYaml (app, yamlPath) {
  const yamlContent = yaml.stringify(app, 2)
  fs.writeFileSync(yamlPath, yamlContent)
}

slugs.forEach((slug) => {
  const basedir = path.join(__dirname, `../apps/${slug}`)
  const yamlFile = `${slug}.yml`
  const yamlPath = path.join(basedir, yamlFile)
  let app
  try {
    app = yaml.load(yamlPath)
  } catch (err) {
    console.log(`Error loading ${yamlPath}`, err)
  }
  removeElectron(app, yamlPath)
  if (!app.category) {
    determineCategory(app, yamlPath)
  }
})

let tags = []
Object.keys(keywordCounts).forEach((keyword) => {
  tags.push({
    tagName: `${keyword}`,
    count: keywordCounts[keyword]
  })
})
tags.sort((a, b) => {
  return b.count - a.count
})

console.log(`Used categories: ${JSON.stringify(usedCategories, null, 2)}`)
console.log(`Keywords unmapped to categories: ${JSON.stringify(tags, null, 2)}`)
