// vValueHelper Tests
var proxiedDescriptor = (()=> {
  var __values = [];

  class proxiedDescriptorClass {
    get [Symbol.toStringTag]() { return 'proxiedDescriptor';}
    valueOf(){return 'pdc'}
  }
  var __composite = { a : '__composite'};
  console.dir(__composite)
  function composite(){
    var o = js.isUndefined(__values[0]) ? __values[0] : js.assign(js.getTypeInfo(__values[0]).create(), ...__values)
    return o;
  }


  let mutableTarget;
  let mutableHandler;

  function setHandler(handler) {
    Object.keys(handler).forEach(key => {
      const value = handler[key];

      if (typeof value !== 'function') {
        // handler[key] = Reflect[key];
        throw new Error(`Trap "${key}: ${value}" is not a function`);
      }

      if (!Reflect[key]) {
        throw new Error(`Trap "${key}: ${value}" is not a valid trap`);
      }
    });
    // mutableHandler = js.assign({}, Reflect, mutableHandler || {}, handler);
    mutableHandler = js.assign(mutableHandler || {}, handler);
    // mutableHandler = handler
  }
  function setTarget(target) {
    // if (!(target instanceof Object)) {
    //   throw new Error(`Target "${target}" is not an object`);
    // }
    mutableTarget = target;
  }
  setTarget(() => {});
  // setHandler(Reflect);
  console.log('-----MT---------')
  console.dir(mutableTarget)
  console.log('-----MT---------')

  // Dynamically forward all the traps to the associated methods on the mutable handler
  const handler = new Proxy({}, {
    get(target, property) {
      console.log('-----marker---------')
      setTarget(composite())
      // console.dir(target)
      // console.dir(Reflect.ownKeys)
      console.log(property)
      if(mutableHandler[property]) return (...args) => mutableHandler[property].apply(null, [mutableTarget, ...args.slice(1)]);
      // else return (...args) => Reflect[property].apply(null, [mutableTarget, ...args.slice(1)]);
    }
  });

  var mutableProxyInstance = {
    setHandler,
    getTarget() {
      return mutableTarget;
    },
    getHandler() {
      return mutableHandler;
    },
    proxy: new Proxy(mutableTarget, handler)
  };
  setHandler({
    
    getOwnPropertyDescriptor: function(target, prop) {
      console.log('accessing prop : ')
      console.dir(prop)
      // console.dir(this)
      o = composite()
      console.dir(target)
      var a = {value : undefined, configurable : true};
      if(!js.isUndefined(o)) a= Object.getOwnPropertyDescriptor(o, prop); 
      
      // if (a) a.value = this.get(o, prop);
      return a;
      // return function(){ 
      //   console.log('in toString ....')
      //   var o = composite();
      //   console.dir(o) 
      //   return o
      // }
    }
    , 
    // ownKeys : function(){
    //   return Reflect.ownKeys(composite())
    // }
    // , 
    get: function(target, name) {
      console.log('accessing name : ')
      console.dir(name)
      console.log('target is now')
      console.dir(target)
      // console.log('' + (name == Symbol.toStringTag))
      // if(name == 'ownKeys') {
      //   return composite().ownKeys;
      // }
      if(js.isUndefined(target)) return Reflect[name];
      if(
        name == util.inspect.custom
          // || name == 'inspect' 
          
          // || name == Symbol.toStringTag
          // || name == Symbol.iterator /*|| name == 'constructor' || name == 'toString' || name == 'valueOf'*/ 
          // || name == 'valueOf'

          // && name != 'name'

          ) {

          
        return function(){ 
          console.log('in toString ....')
          var o = composite();
          console.dir(o) 
          return o
        }
      }
      // else if(
      //   name == Symbol.toStringTag
      //   // ||   
      //   // name == 'toString'
      //   ||  name == 'valueOf'
      //   || name == Symbol.iterator /*|| name == 'constructor' || name == 'toString' || name == 'valueOf'*/ 
      //   ) 
      //   return JSON.stringify((function(){ 
      //       console.log('in toString ....')
      //       var o = composite();
      //       // console.dir(o) 
      //       return o
      //     })()
      //   )
      // else 
      return (name == 'composite' ? composite()
      // : name == 'toString' || name == 'valueOf' ? (function(){ 
      //   console.log('in toString')
      //   // console.dir((js.isUndefined(__values[0]) ? __values[0] : js.assign(js.getTypeInfo(__values[0]).create(), ...__values))) 
      //   return composite() 
      // })
      // : name == 'toValue' ? js.assign(js.getTypeInfo(__values[0]).create(), ...__values)
      : name == 'current' ? Ref.isRef(__values[0]) ? __values[0].getValue() : __values[0]
      : name == 'previous' ? Ref.isRef(__values[1]) ? __values[1].getValue() : __values[1]
      : composite()[name] //Ref.isRef(__values[name]) ? __values[name].getValue() : __values[name]
      )
    }
    , set: function(target, name, value) {
      mutabletarget = __composite = composite();
      name == 'revise' ? (__values.splice(0, 0, value), value) 
        :  name == 'precede' ? (__values.push(value), value)
        :  name == 'current' ? __values[0] = value
        : __values[name] = value;
      return __composite;
    }
  })

  var p =  new Proxy(__composite, handler);
  p.toString = function() { return 'ps tostring' }
  return {
      get : function(){ return p}
    , set : function(value) { p.revise = value}
  }
})()