'use strict'

const argv = require('yargs')
  .example('$ npm run validation', 'validate cson of all locales')
  .example('$ npm run validation -- --locale fr zh-tw', 'validate cson in fr/* and zh-tw/*')
  .array('locale')
  .describe('locale', 'specify list of locales')
  .help('h')
  .argv

const fs = require('fs')
const path = require('path')
const CSON = require('cson')
const { expect } = require('chai')

const { flattenObj } = require('./util.js')
const LOCALES = require('./locales.js')
const CsonFiles = require('./defs.js')

describe('validation', () => {

  let packageMeta = {}

  describe('package.json validation', () => {

    it('loads package.json', () => {
      const loading = () => {
        packageMeta = JSON.parse(fs.readFileSync('./package.json'), 'utf8')
      }
      expect(loading, 'load package.json error').not.to.throw(Error)
    })

    it('checks locale options list in configSchema in package.json', () => {
      const locales = packageMeta.configSchema.locale.enum.map((opt)=>{return opt.value})
      expect(locales, 'inconsistent locale options').to.deep.equal(LOCALES)
    })
  })

  describe('cson file validation', () => {

    describe('checking each cson files of all locales', () => {
      const templateKeys = {}
      for (let csonFile of CsonFiles) {
        templateKeys[csonFile] = Object.keys(flattenObj(CSON.load(path.join(__dirname, '../def/template', csonFile))))
      }

      for (let locale of (argv.locale || LOCALES)) {
        describe(`checking locale ${locale}`, () => {
          for (let csonFile of CsonFiles) {

            describe(`checking "${path.join(locale, csonFile)}"`, () => {

              const cson = CSON.load(path.join(__dirname, '../def', locale, csonFile))
              const flattenCson = flattenObj(cson)

              it('has no error loading cson', () => {
                expect(cson, 'load cson error').not.to.be.instanceof(Error)
              })
              it('has consistent flatten keys with template', () => {
                expect(Object.keys(flattenCson), 'inconsistent keys').to.deep.equal(templateKeys[csonFile])
              })
              it('has no special char in values of cson', () => {
                for (let k in flattenCson) {
                  const specialChr = /[~@#%^*]/g
                  const _str = flattenCson[k].toString()
                  const _res = _str.search(specialChr)
                  const errMsg = `\n\tfound special chr: '${_str[_res]}' in value: '${_str}'\n\n\tcson-path: '${k}'\t`
                  expect(_res, errMsg).to.equal(-1)
                }
              })
              if (csonFile === 'menu_linux.cson' || csonFile === 'menu_win32.cson') {
                it('has valid hotkey hints if required', () => {
                  for (let k in flattenCson) {
                    const menuItemName = k.split('.').slice(-2, -1).shift()
                    const _str = flattenCson[k]
                    const hasAmpersand = menuItemName.match(/&/g)
                    if (hasAmpersand) {
                      const hotkeyHintRegex = /&\w/g
                      const errMsg = `\n\tinvalid or missing hotkey hint in '${_str}'\n\n\tcson-path: '${k}'\t`
                      expect(_str.search(hotkeyHintRegex), errMsg).to.not.equal(-1)
                    }
                  }
                })
              }

            })
          }
        })
      }   // end of for loop of locales

    })   // end of checking each cson files of all locales

  })   // end of cson file validation

})   // end of validation

@@ -566,32 +566,8 @@
  %7B%0A%0A
-  let packageMeta = %7B%7D%0A%0A
   de
@@ -603,24 +603,49 @@
 on', () =%3E %7B
+%0A    let packageMeta = %7B%7D
 %0A%0A    it('lo
@@ -1006,22 +1006,14 @@
 map(
-(
 opt
-)
+ 
 =%3E
-%7Breturn
  opt
@@ -1018,17 +1018,16 @@
 pt.value
-%7D
 )%0A      
@@ -1257,39 +1257,37 @@
     
-for (let csonFile of C
+CsonFiles.forEach(c
 sonFile
-s)
+ =%3E
  %7B%0A 
@@ -1411,24 +1411,25 @@
 %0A      %7D
+)
 %0A%0A      
 for (let
@@ -1424,23 +1424,20 @@
     
-for (le
+cons
 t locale
  of 
@@ -1436,13 +1436,12 @@
 cale
- of (
+s = 
 argv
@@ -1462,13 +1462,44 @@
 ALES
-))
+%0A      locales.forEach(locale =%3E
  %7B%0A
+%0A
     
@@ -1540,32 +1540,33 @@
 cale%7D%60, () =%3E %7B%0A
+%0A
           for (l
@@ -1563,39 +1563,37 @@
     
-for (let csonFile of C
+CsonFiles.forEach(c
 sonFile
-s)
+ =%3E
  %7B%0A%0A
@@ -2234,34 +2234,45 @@
     
-for (let k in flattenCson)
+Object.keys(flattenCson).forEach(k =%3E
  %7B%0A 
@@ -2611,32 +2611,33 @@
                %7D
+)
 %0A              %7D
@@ -2811,34 +2811,45 @@
     
-for (let k in flattenCson)
+Object.keys(flattenCson).forEach(k =%3E
  %7B%0A 
@@ -3359,32 +3359,33 @@
                %7D
+)
 %0A               
@@ -3423,32 +3423,33 @@
   %7D)%0A          %7D
+)
 %0A        %7D)%0A    
@@ -3451,16 +3451,17 @@
 %0A      %7D
+)
    // en
@@ -3469,16 +3469,19 @@
  of 
-for loop
+each locale
  of 

refactor validation.js: apply functional programming to replace for loop