// 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 Deferred = require('../lib/deferred');
var Promise = require('../lib/promise');
var TaskSequence = require('../lib/task-sequence');
var promiseFor = require('../lib/async-helper').promiseFor;
var promiseWhile = require('../lib/async-helper').promiseWhile;

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.
 * @param {module:vanadium.vom.TypeDecoder} typeDecoder The type decoder to
 * use.  This can be null.
 * @memberof module:vanadium.vom
 * @constructor
 */
function Decoder(messageReader, deepWrap, typeDecoder) {
  this._messageReader = messageReader;
  this._typeDecoder = typeDecoder || new TypeDecoder();
  this._deepWrap = false;
  this._tasks = new TaskSequence();
}

/*
 * 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(cb) {
  var def = new Deferred(cb);
  var decoder = this;
  this._tasks.addTask(function() {
    return decoder._messageReader.nextMessageType(decoder._typeDecoder).
      then(function(type) {
      if (type === null) {
        return null;
      }
      var reader = decoder._messageReader.rawReader;
      return decoder._decodeValue(type, reader, true);
    }).then(function(v) {
      def.resolve(v);
    }, function(err) {
      def.reject(err);
    });
  });
  return def.promise;
};

Decoder.prototype._decodeValue = function(t, reader, shouldWrap) {
  return this._decodeUnwrappedValue(t, reader).then(function(value) {
    // 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);
      if (Ctor.prototype._wrappedType) {
        return new Ctor(value);
      }
      if (value !== null && value !== undefined) {
        Object.defineProperty(value, 'constructor', {
          value: Ctor,
        });
      }
    }
    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 reader.readFloat().then(function(real) {
         return reader.readFloat().then(function(imag) {
           return {
             real: real,
             imag: imag
           };
         });
      });
    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 decoder = this;
      var typeId;
      return reader.readUint().then(function(tId) {
        typeId = tId;
        return decoder._typeDecoder.lookupType(typeId);
      }).then(function(type) {
        if (type === undefined) {
          throw new Error('Undefined type for TYPEOBJECT id ' + typeId);
        }
        return type;
      });

    default:
      return Promise.reject(new Error('Support for decoding kind ' + t.kind +
        ' not yet implemented'));
  }
};

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

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

Decoder.prototype._decodeArray = function(t, reader) {
  var decoder = this;
  // Consume the zero byte at the beginning of the array.
  return reader.readByte().then(function(b) {
    if (b !== 0) {
      throw new Error('Unexpected length ' + b);
    }
    return decoder._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 reader._readRawBytes(len).then(function(b) {
      return new Uint8Array(b);
    });
  }

  var arr = new Array(len);
  var i = 0;
  var decoder = this;
  return promiseFor(len, function() {
    return decoder._decodeValue(t.elem, reader, false).then(function(val) {
      arr[i] = val;
      i++;
    });
  }).then(function() {
    return arr;
  });
};

Decoder.prototype._decodeSet = function(t, reader) {
  var decoder = this;
  var s = new Set();
  return reader.readUint().then(function(len) {
    return promiseFor(len, function() {
      return decoder._decodeValue(t.key, reader, false).then(function(key) {
        s.add(key);
      });
    });
  }).then(function() {
    return s;
  });
};

Decoder.prototype._decodeMap = function(t, reader) {
  var decoder = this;
  return reader.readUint().then(function(len) {
    var m = new Map();
    var i = 0;
    if (len > 0) {
      return decoder._decodeValue(t.key, reader, false).then(handleKey);
    }
    return m;

    function handleKey(key) {
      return decoder._decodeValue(t.elem, reader, false).then(function(value) {
        m.set(key, value);
        i++;
        if (i < len) {
          return decoder._decodeValue(t.key, reader, false).then(handleKey);
        }
        return m;
      });
    }
  });
};

Decoder.prototype._decodeStruct = function(t, reader) {
  var decoder = this;
  var Ctor = Registry.lookupOrCreateConstructor(t);
  var obj = Object.create(Ctor.prototype);

  return promiseWhile(notEndByte, readField).then(function() {
    return obj;
  }).then(function(obj) {
    t.fields.forEach(function(field) {
      var name = util.uncapitalize(field.name);
      if (!obj.hasOwnProperty(name)) {
        obj[name] = unwrap(canonicalize.zero(field.type));
      }
    });
    return obj;
  });
  function notEndByte() {
    return reader.tryReadControlByte().then(function(ctrl) {
      if (ctrl === endByte) {
        return false;
      }

      if (ctrl) {
        throw new Error('Unexpected control byte ' + ctrl);
      }
      return true;
    });
  }
  function readField() {
    var name = '';
    return reader.readUint().then(function(nextIndex) {
      if (t.fields.length <= nextIndex) {
        throw new Error('Struct index ' + nextIndex + ' out of bounds');
      }
      var field = t.fields[nextIndex];
      name = util.uncapitalize(field.name);
      return decoder._decodeValue(field.type, reader, false);
    }).then(function(val) {
      obj[name] = val;
    });
  }
};

Decoder.prototype._decodeOptional = function(t, reader) {
  var decoder = this;
  return reader.peekByte().then(function(isNil) {
    if (isNil === nilByte) {
      // We don't have to wait for the read to finish.
      reader.readByte();
      return null;
    }
    return decoder._decodeValue(t.elem, reader, false);
  });
};

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

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

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