#!/usr/bin/env node

'use strict'
require('coffee-script').register()
const pkg = require('../package.json')
require('update-notifier')({ pkg }).notify()

const fs = require('fs')
const os = require('os')
const path = require('path')
const createLogger = require('acho')
const loggerSkinCLI = require('acho-skin-cli')

const finepack = require('./../lib/Finepack')

const isPrivate = (filepath) => {
  try {
    return JSON.parse(filepath).private
  } catch (err) {
    return false
  }
}

const cli = require('meow')({
  pkg,
  help: [
    'Usage',
    '  $ finepack <fileJSON> [options]',
    '\n  options:',
    '\t --no-validate\t\t   disable validate mode.',
    '\t --no-color\t\t   disable colors in the output.',
    '\t --sort-ignore-object-at   don\'t sort object(s) at these comma separated key(s).',
    '\t --sort-ignore-array-at    don\'t sort array(s) at these comma separated key(s).',
    '\t --version\t\t   output the current version.',
    '\n  examples:',
    '\t finepack package.json',
    '\t finepack bower.json --no-validate'
  ].join('\n')
})

if (cli.input.length === 0) cli.showHelp()

const cliFlagCsvToArray = (flagName) =>
  cli.flags[flagName].toString().split(',').filter(e => e)

const filepath = path.resolve(cli.input[0])
const filename = path.basename(filepath)

let options = {
  filename,
  validate: cli.flags.validate || isPrivate(filepath),
  color: cli.flags.color
}

let sortOptions = {}

if (cli.flags.sortIgnoreObjectAt) {
  const ignoreObjectAtKeys = cliFlagCsvToArray('sortIgnoreObjectAt')

  if (ignoreObjectAtKeys.length) {
    sortOptions = Object.assign({}, sortOptions, { ignoreObjectAtKeys })
  }
}

if (cli.flags.sortIgnoreArrayAt) {
  const ignoreArrayAtKeys = cliFlagCsvToArray('sortIgnoreArrayAt')

  if (ignoreArrayAtKeys.length) {
    sortOptions = Object.assign({}, sortOptions, { ignoreArrayAtKeys })
  }
}

options = Object.assign({}, options, { sortOptions })

const stringify = (data) => {
  return JSON.stringify(data, null, 2) + os.EOL
}

fs.readFile(filepath, { encoding: 'utf8' }, (err, filedata) => {
  if (err) throw err

  finepack(filedata, options, (error, output, messages) => {
    const log = createLogger({
      types: loggerSkinCLI,
      keyword: 'symbol',
      color: options.color,
      messages: messages
    })

    if (error) {
      log.print()
      log.error(output)
      return process.exit(1)
    }

    output = stringify(output)
    fs.writeFile(filepath, output, { encoding: 'utf8' }, (err) => {
      if (err) throw err
      console.log()
      log.print()
    })
  })
})

@@ -355,24 +355,86 @@
 Finepack')%0A%0A
+const isNil = value =%3E value === undefined %7C%7C value === null%0A%0A
 const isPriv
@@ -439,25 +439,24 @@
 ivate = 
-(
 filepath
 ) =%3E %7B%0A 
@@ -447,17 +447,16 @@
 filepath
-)
  =%3E %7B%0A  
@@ -770,33 +770,33 @@
 e output.',%0A    
-'
+%22
 %5Ct --sort-ignore
@@ -807,25 +807,24 @@
 ect-at   don
-%5C
 't sort obje
@@ -857,32 +857,32 @@
 ated key(s).
-'
+%22
 ,%0A    
-'
+%22
 %5Ct --sort-ig
@@ -901,17 +901,16 @@
 t    don
-%5C
 't sort 
@@ -950,17 +950,17 @@
  key(s).
-'
+%22
 ,%0A    '%5C
@@ -1117,16 +1117,97 @@
 in('%5Cn')
+,%0A  flags: %7B%0A    validate: %7B%0A      type: 'boolean',%0A      default: true%0A    %7D%0A  %7D
 %0A%7D)%0A%0Aif 
@@ -1277,17 +1277,16 @@
 y = 
-(
 flagName
 ) =%3E
@@ -1281,17 +1281,16 @@
 flagName
-)
  =%3E%0A  cl
@@ -1471,16 +1471,22 @@
 lidate: 
+isNil(
 cli.flag
@@ -1495,19 +1495,23 @@
 validate
- %7C%7C
+)%0A    ?
  isPriva
@@ -1522,16 +1522,41 @@
 ilepath)
+%0A    : cli.flags.validate
 ,%0A  colo
@@ -2113,14 +2113,12 @@
 y = 
-(
 data
-)
  =%3E 
@@ -2585,24 +2585,25 @@
 ify(output)%0A
+%0A
     fs.write
@@ -2647,21 +2647,19 @@
 tf8' %7D, 
-(
 err
-)
  =%3E %7B%0A  

Enable validate by default