import { toPath } from 'lodash'

function getValue<ValueObject>(container: ValueObject, path: string) {
  const elements = toPath(path)
  let obj: any = container
  for (let element of elements) {
    obj = obj[element as keyof object]
  }
  return obj
}

function recursiveSet<ValueObject>(
  object: ValueObject,
  path: string[],
  value: any
): any {
  if (path.length === 0) {
    return value
  }
  if (object instanceof Array) {
    const index = parseInt(path[0])
    return [
      ...object.slice(0, index),
      recursiveSet(object[index], path.slice(1), value),
      ...object.slice(index + 1)
    ]
  } else {
    const index = path[0]
    return {
      ...object,
      [index]: recursiveSet(object[index as keyof object], path.slice(1), value)
    }
  }
}

function setValue<ValueObject>(
  container: ValueObject,
  path: string,
  value: any
) {
  const elements = toPath(path)
  return recursiveSet(container, elements, value)
}

export { getValue, setValue }
