// 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 Represents a VOM decoder.
 * @private
 */

module.exports = Decoder;

var canonicalize = require('../vdl/canonicalize.js');
var TypeDecoder = require('./type-decoder.js');
var kind = require('../vdl/kind.js');
var Registry = require('../vdl/registry.js');
var types = require('../vdl/types.js');
var util = require('../vdl/util.js');
var unwrap = require('../vdl/type-util').unwrap;
var wiretype = require('../gen-vdl/v.io/v23/vom');
var nativeTypeRegistry = require('../vdl/native-type-registry');

var endByte = unwrap(wiretype.WireCtrlEnd);
var nilByte = unwrap(wiretype.WireCtrlNil);

/**
 * Create a decoder to read objects from the provided message reader.
 * Decode has the option of returning a deeply-wrapped object, or an object only
 * wrapped at the top-level.
 * @param {module:vanadium.vom.ByteArrayMessageReader} reader The message
 * reader.
 * @param {boolean=} deepWrap Whether to deeply wrap. Defaults to false.
 * @memberof module:vanadium.vom
 * @constructor
 */
function Decoder(messageReader, deepWrap) {
  this._messageReader = messageReader;
  this._typeDecoder = new TypeDecoder();
  this._deepWrap = deepWrap || false;
}

/*
 * TODO(bprosnitz) We will want to be able to decode when we get callbacks.
 * Revisit this API.
 */
/**
 * Decodes the next object off of the message reader.
 * @return {object} The next object or null if no more objects are available.
 */
Decoder.prototype.decode = function() {
  var type = this._messageReader.nextMessageType(this._typeDecoder);
  if (type === null) {
    return null;
  }
  var reader = this._messageReader.rawReader;
  return this._decodeValue(type, reader, true);
};

Decoder.prototype._decodeValue = function(t, reader, shouldWrap) {
  var value = this._decodeUnwrappedValue(t, reader);

  // Special: JSValue should be reduced and returned as a native value.
  if (types.JSVALUE.equals(t)) {
    return canonicalize.reduce(value, types.JSVALUE);
  }

  if (nativeTypeRegistry.hasNativeType(t)) {
    return canonicalize.reduce(value, t);
  }
  // If this value should be wrapped, apply the constructor.
  if (t.kind !== kind.TYPEOBJECT && shouldWrap) {
    var Ctor = Registry.lookupOrCreateConstructor(t);
    return new Ctor(value, this._deepWrap);
  }
  return value;
};

Decoder.prototype._decodeUnwrappedValue = function(t, reader) {
  switch (t.kind) {
    case kind.BOOL:
      return reader.readBool();
    case kind.BYTE:
      return reader.readByte();
    case kind.UINT16:
    case kind.UINT32:
      return reader.readUint();
    case kind.UINT64:
      return reader.readBigUint();
    case kind.INT16:
    case kind.INT32:
      return reader.readInt();
    case kind.INT64:
      return reader.readBigInt();
    case kind.FLOAT32:
    case kind.FLOAT64:
      return reader.readFloat();
    case kind.COMPLEX64:
    case kind.COMPLEX128:
      return {
        real: reader.readFloat(),
        imag: reader.readFloat()
      };
    case kind.STRING:
      return reader.readString();
    case kind.ENUM:
      return this._decodeEnum(t, reader);
    case kind.LIST:
      return this._decodeList(t, reader);
    case kind.ARRAY:
      return this._decodeArray(t, reader);
    case kind.SET:
      return this._decodeSet(t, reader);
    case kind.MAP:
      return this._decodeMap(t, reader);
    case kind.STRUCT:
      return this._decodeStruct(t, reader);
    case kind.UNION:
      return this._decodeUnion(t, reader);
    case kind.ANY:
      return this._decodeAny(reader);
    case kind.OPTIONAL:
      return this._decodeOptional(t, reader);
    case kind.TYPEOBJECT:
      var typeId = reader.readUint();
      var type = this._typeDecoder.lookupType(typeId);
      if (type === undefined) {
        throw new Error('Undefined type for TYPEOBJECT id ' + typeId);
      }
      return type;
    default:
      throw new Error('Support for decoding kind ' + t.kind +
        ' not yet implemented');
  }
};

Decoder.prototype._decodeEnum = function(t, reader) {
  var index = reader.readUint();
  if (t.labels.length <= index) {
    throw new Error('Invalid enum index ' + index);
  }
  return t.labels[index];
};

Decoder.prototype._decodeList = function(t, reader) {
  var len = reader.readUint();
  return this._readSequence(t, len, reader);
};

Decoder.prototype._decodeArray = function(t, reader) {
  // Consume the zero byte at the beginning of the array.
  var b = reader.readByte();
  if (b !== 0) {
    throw new Error('Unexpected length ' + b);
  }
  return this._readSequence(t, t.len, reader);
};

Decoder.prototype._readSequence = function(t, len, reader) {
  if (t.elem.kind === kind.BYTE) {
    // Read byte sequences directly into Uint8Arrays.

    // The Uint8Array is created by calling subarray. In node, this means that
    // its buffer points to the whole binary_reader buffer. To fix this, we
    // recreate the Uint8Array here to avoid exposing it.
    return new Uint8Array(reader._readRawBytes(len));
  }

  var arr = new Array(len);
  for (var i = 0; i < len; i++) {
    arr[i] = this._decodeValue(t.elem, reader, false);
  }
  return arr;
};

Decoder.prototype._decodeSet = function(t, reader) {
  var len = reader.readUint();
  var s = new Set();
  for (var i = 0; i < len; i++) {
    var key = this._decodeValue(t.key, reader, false);
    s.add(key);
  }
  return s;
};

Decoder.prototype._decodeMap = function(t, reader) {
  var len = reader.readUint();
  var m = new Map();
  for (var i = 0; i < len; i++) {
    var key = this._decodeValue(t.key, reader, false);
    var val = this._decodeValue(t.elem, reader, false);
    m.set(key, val);
  }
  return m;
};

Decoder.prototype._decodeStruct = function(t, reader) {
  var Ctor = Registry.lookupOrCreateConstructor(t);
  var obj = Object.create(Ctor.prototype);
  while (true) {
    var ctrl = reader.tryReadControlByte();
    if (ctrl === endByte) {
      break;
    }

    if (ctrl) {
      throw new Error('Unexpected control byte ' + ctrl);
    }

    var nextIndex = reader.readUint();
    if (t.fields.length <= nextIndex) {
      throw new Error('Struct index ' + nextIndex + ' out of bounds');
    }
    var field = t.fields[nextIndex];
    var val = this._decodeValue(field.type, reader, false);
    obj[util.uncapitalize(field.name)] = val;
  }
  return obj;
};

Decoder.prototype._decodeOptional = function(t, reader) {
  var isNil = reader.peekByte();
  if (isNil === nilByte) {
    reader.readByte();
    return null;
  }
  return this._decodeValue(t.elem, reader, false);
};

Decoder.prototype._decodeAny = function(reader) {
  var ctrl = reader.tryReadControlByte();
  if (ctrl === nilByte) {
    return null;
  }

  if (ctrl) {
    throw new Error('Unexpected control byte ' + ctrl);
  }
  var typeId = reader.readUint();
  var type = this._typeDecoder.lookupType(typeId);
  if (type === undefined) {
    throw new Error('Undefined typeid ' + typeId);
  }
  return this._decodeValue(type, reader, true);
};

Decoder.prototype._decodeUnion = function(t, reader) {
  // Find the Union field that was set and decode its value.
  var fieldIndex = reader.readUint();
  if (t.fields.length <= fieldIndex) {
    throw new Error('Union index ' + fieldIndex + ' out of bounds');
  }
  var field = t.fields[fieldIndex];
  var val = this._decodeValue(field.type, reader, false);

  // Return the Union with a single field set to its decoded value.
  var Ctor = Registry.lookupOrCreateConstructor(t);
  var obj = Object.create(Ctor.prototype);
  obj[util.uncapitalize(field.name)] = val;
  return obj;
};
