'use strict'

const SPLIT_REG_EXP = /[[\]]/g

/**
 * This class allows to set or get specific
 * values within a json data structure using
 * string-based paths
 *
 * @param {String} path A path, e.g. users[2].firstname
 *
 * @constructor
 */
function setValue (root, path, value) {
  const tokens = tokenize(path)
  let node = root

  let i
  for (i = 0; i < tokens.length - 1; i++) {
    const token = tokens[i]

    if (node[token] !== undefined) {
      if (typeof node[token] !== 'object') {
        if (typeof tokens[i + 1] === 'number') {
          node = node[token] = []
        } else {
          node = node[token] = {}
        }
      } else {
        node = node[token]
      }
    } else if (typeof tokens[i + 1] === 'number') {
      node = node[token] = []
    } else {
      node = node[token] = {}
    }
  }

  node[tokens[i]] = value
}

/**
 * Parses the path. Splits it into
 * keys for objects and indices for arrays.
 *
 * @private
 * @returns {void}
 */
function tokenize (path) {
  const tokens = []

  const parts = path.split('.')

  for (let i = 0; i < parts.length; i++) {
    const part = parts[i].trim()

    if (part.length === 0) {
      continue
    }

    const arrayIndexes = part.split(SPLIT_REG_EXP)

    tokens.push(arrayIndexes[0])

    for (let j = 1; j < arrayIndexes.length; j++) {
      if (arrayIndexes[j].length === 0) {
        continue
      }

      tokens.push(Number(arrayIndexes[j]))
    }
  }
  return tokens
}

module.exports = {
  setValue
}

@@ -441,30 +441,20 @@
 ndefined
-) %7B%0A      if (
+ && 
 typeof n
@@ -464,19 +464,19 @@
 %5Btoken%5D 
-!
 ==
+=
  'object
@@ -490,195 +490,26 @@
     
-  if (typeof tokens%5Bi + 1%5D === 'number') %7B%0A          node = node%5Btoken%5D = %5B%5D%0A        %7D else %7B%0A          node = node%5Btoken%5D = %7B%7D%0A        %7D%0A      %7D else %7B%0A        node = node%5Btoken%5D%0A      %7D
+node = node%5Btoken%5D
 %0A   

simplify json path handling