// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

/**
 * @fileoverview Converts native JavaScript values to and from JSValue
 * The outputted JSValues are not necessarily canonical, nor in the same form.
 * For example, a Set turns into a list of its keys, and Map and Object become
 * a list of key-value pairs.
 * This file should not be exported at the top-level; it is meant to be used by
 * canonicalize only. It is unit-tested separately.
 * @private
 */

var typeUtil = require('./type-util.js');
var types = require('./types.js');
var util = require('./util.js');
require('./es6-shim');

module.exports = {
  fromNative: convertFromNative,
  toNative: convertToNative
};

// There is only a single JSValueConstructor.
// In order to avoid any cyclical dependencies, this constructor is obtained
// from the registry with delayed dependency injection.
// TODO(alexfandrianto): Can this be obtained from a VDL file that defines the
// JSValue? A potential issue is that VDL-generated files require 'vom', and
// this is the 'vom' library.
var JSValueConstructor = null;
function getJSValueConstructor() {
  if (JSValueConstructor === null) {
    var Registry = require('./registry.js');
    JSValueConstructor = Registry.lookupOrCreateConstructor(types.JSVALUE);
  }
  return JSValueConstructor;
}
/**
 * Convert the given raw value into the proper JSValue form.
 * Note: Skips typed values, so it will not convert any native values there.
 * Excluding undefined, raw values satisfy the following equality:
 * convertToNative(convertFromNative(val)) === val
 * @private
 * @param {*} val The value to be molded into a JSValue.
 * @return {*} The JSValue.
 */
function convertFromNative(val) {
  // No need to convert if val is already a JSValue or typed object.
  // Note: In this case, val is NOT a new reference.
  if (typeUtil.isTyped(val)) {
    return val;
  }

  // Associate the JSValue prototype with the returned object.
  // Avoids using 'new JSValue(...)' because that would call canonicalize.
  var JSValue = getJSValueConstructor();
  var ret = Object.create(JSValue.prototype);

  if (val === undefined || val === null) {
    ret.null = {}; // must be the 'empty struct', but any value will do.
  } else if (typeof val === 'boolean') {
    ret.boolean = val;
  } else if (typeof val === 'number') {
    ret.number = val;
  } else if (typeof val === 'string') {
    ret.string = val;
  } else if (typeof val !== 'object') {
    // From here on, only objects can convert to JSValue.
    throw new TypeError('Cannot convert a ' + (typeof val) + ' to JSValue');
  } else if (val instanceof Uint8Array) {
    ret.bytes = new Uint8Array(val);
  } else if (Array.isArray(val)) {
    ret.list = val.map(function(elem) {
      return convertFromNative(elem);
    });
  } else if (val instanceof Set) {
    // Set: Return a []JSValue
    var keys = [];
    val.forEach(function(key) {
      keys.push(convertFromNative(key));
    });
    ret.set = keys;
  } else if (val instanceof Map) {
    // Map: Return []{key, value pairs}
    var keyVals = [];
    val.forEach(function(elem, key) {
      keyVals.push({
        'key': convertFromNative(key),
        'value': convertFromNative(elem)
      });
    });
    ret.map = keyVals;
  } else {
    // defaults to... Object: Return []{string key, value pairs}
    // Note: Ignores 'private' fields: keys that start with '_'
    ret.object = Object.keys(val).filter(util.isExportedStructField).map(
      function(key) {
        return {
          'key': key,
          'value': convertFromNative(val[key])
        };
      }
    );
  }
  return ret;
}

/**
 * Convert the given JSValue into the proper raw value.
 * Note: Skips conversion of non-JS values.
 * Excluding undefined, raw values satisfy the following equality:
 * convertToNative(convertFromNative(val)) === val
 * @private
 * @param{JSValue} jsval The JSValue to be restored into raw form.
 * @return The raw value
 */
function convertToNative(jsval) {
  // No need to convert if jsval lacks type or isn't of type JSValue.
  if (!typeUtil.isTyped(jsval) || !types.JSVALUE.equals(jsval._type)) {
    return jsval;
  }
  if (jsval === undefined) {
    return null;
  }

  // jsval is in the Union format. Extract its value, ignoring keys associated
  // with undefined values.
  var jsvalKey = util.getFirstDefinedPropertyKey(jsval);
  if (jsvalKey === undefined) {
    throw new Error('could not convert from JSValue. given: ' +
      JSON.stringify(jsval));
  }
  var jsvalElem = jsval[jsvalKey];
  return convertToNativeInternal(jsvalKey, jsvalElem);
}

// Based on the key and internal JSValue, return the raw value.
function convertToNativeInternal(jsvalKey, jsvalElem) {
  switch(jsvalKey) {
    case 'null':
      return null;
    case 'boolean':
    case 'number':
    case 'string':
    case 'bytes':
      return jsvalElem;
    case 'list':
      var list = new Array(jsvalElem.length);
      for (var i = 0; i < jsvalElem.length; i++) {
        list[i] = convertToNative(jsvalElem[i]);
      }
      return list;
    case 'set':
      var set = new Set();
      jsvalElem.forEach(function(j) {
        set.add(convertToNative(j));
      });
      return set;
    case 'map':
      var map = new Map();
      jsvalElem.forEach(function(j) {
        map.set(
          convertToNative(j.key),
          convertToNative(j.value)
        );
      });
      return map;
    case 'object':
      var object = {};
      jsvalElem.forEach(function(j) {
        object[j.key] = convertToNative(j.value);
      });
      return object;
    default:
      throw new Error('unknown JSValue key ' + jsvalKey + ' with value ' +
        jsvalElem);
  }
}
