// 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.
 * @memberof module:vanadium.vom
 * @constructor
 */
function Decoder(messageReader, deepWrap) {
  this._messageReader = messageReader;
  this._typeDecoder = new TypeDecoder();
  this._deepWrap = 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);
      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 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;
      return reader.readUint().then(function(typeId) {
        var type = decoder._typeDecoder.lookupType(typeId);
        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;
  });
  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);
    }
    return reader.readUint().then(function(typeId) {
      var type = decoder._typeDecoder.lookupType(typeId);
      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;
  });
};
