import merge from '../merge'
import subscriber from '../subscriber'
import iterator from '../iterator'
import setVal from '../val'
import { get$, get$switch, get$any } from '../../../get'
// import hash from 'string-hash'
import { parse, puid } from 'brisky-struct'

export default (t, map) => {
  const props = t.get('props')
  const child = props.default.struct

  const $ = get$(t)

  child.key = 'default'
  if (t._c || t !== child._p) {
    child._c = t
    child._cLevel = 1
  }

  var key = '$any'
  var $any = get$any(t)
  var extra

  if (typeof $any === 'function') {
    key = '$any' + puid(t)
  } else if (typeof $any === 'object') {
    extra = parse($any)

    $any = $any.val
    key = '$any' + puid(t)
  } else {
    $any = false
  }

  if ($.length !== 1) {
    const path = $.slice(0, -1)
    const val = { val: 'switch' } // wrong for switch .. what to do
    let walk = map
    let exists
    val[key] = child.$map(void 0, exists ? walk : val)

    if ($any) {
      val[key].$keys = $any
    }

    if (!val[key].val) {
      if (!get$switch(child)) {
        setVal(child, val[key], 'switch')
      }
    }
    // if (!child.$test && child.sync !== false && val.$any._.sync === true) {
    //   val.$any._.sync = 1
    // }
    map = merge(t, path, val, map)
  } else {
    if (map[key]) {
      merge(t, [ key ], child.$map(void 0, map), map)
    } else {
      map[key] = child.$map(void 0, map)
    }

    if (!map[key].val) {
      if (!get$switch(child)) {
        setVal(child, map[key], 'switch')
      }
    }

    if ($any) {
      map[key].$keys = $any
    }
    // if (!child.$test && child.sync !== false && map.$any._.sync === true) {
    //   map.$any._.sync = 1
    // }
  }

  iterator(t, map)
  subscriber(map, t, 't')

  if (extra) {
    mergeExtra(extra, map[key])
  }

  return map
}

const $keys = (map, i, t) => {
  if (typeof map.$keys !== 'object') {
    map.$keys = { val: map.$keys }
  }
  if (i === 'parent') {
    for (let j in t) {
      map.$keys[j] = t[j]
    }
  } else if (i === 'root') {
    map.$keys.root = {}
    for (let j in t) {
      map.$keys.root[j] = t[j]
    }
  } else {
    map.$keys[i] = t
  }
}

const mergeExtra = (target, map, deep) => {
  for (let i in target) {
    let t = target[i]
    if (!deep) { //  && (i === 'root' || i === 'parent')
      $keys(map, i, t)
    } else {
      let type = typeof t
      if (type !== 'object' && type !== 'function') {
        t = target[i] = { val: t }
      }
      if (i === 'val') {
        if (!deep) {
          if (!map.val) {
            map.val = t
          } else if (t === true && map.val === 'switch') {
            map.val = t
          }
        }
      } else {
        if (!(i in map)) {
          map[i] = t
        } else {
          mergeExtra(t, map[i], true)
        }
      }
    }
  }
}

@@ -185,42 +185,8 @@
 et'%0A
-// import hash from 'string-hash'%0A
 impo
@@ -838,42 +838,8 @@
  do%0A
-    let walk = map%0A    let exists%0A
     
@@ -871,24 +871,8 @@
 d 0,
- exists ? walk :
  val
@@ -1042,124 +1042,8 @@
   %7D%0A
-    // if (!child.$test && child.sync !== false && val.$any._.sync === true) %7B%0A    //   val.$any._.sync = 1%0A    // %7D
 %0A   
@@ -1390,89 +1390,172 @@
 %7D%0A  
-  // if (!child.$test && child.sync !== false && map.$any._.sync === true
+%7D%0A%0A  iterator(t, map)%0A  subscriber(map, t, 't')%0A%0A  if (extra) %7B%0A    mergeExtra(extra, map%5Bkey%5D)%0A    const $keys = map%5Bkey%5D.$keys%0A    for (let field in $keys
 ) %7B%0A    
 //  
@@ -1554,112 +1554,201 @@
     
+ 
+ 
 // 
-  map.$any._.sync = 1%0A    // %7D%0A  %7D%0A%0A  iterator(t, map)%0A  subscriber(map, t, 't')%0A%0A  if (extra
+tmp expiriment%0A      if (field !== '$object' && field !== 'props' && field !== 'val' && field !== 'root') %7B%0A        // console.log(field, $keys%5Bfield%5D)%0A        if (!map%5Bkey%5D%5Bfield%5D
 ) %7B%0A    
 merg
@@ -1747,35 +1747,68 @@
     
+  
-mergeExtra(extra, map%5Bkey%5D)
+    map%5Bkey%5D%5Bfield%5D = $keys%5Bfield%5D%0A        %7D%0A      %7D%0A    %7D
 %0A  %7D

add drivers to subscription