// 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 Type decoder handles decoding types from a VOM stream by
 * looking up by id.
 *
 * Definitions:
 * Type / Defined Type - The standard VOM JavaScript type object representation.
 * Partial Type - The type representation off the wire, identical to defined
 * types but child types are described by type ids rather than actual complete
 * type objects.
 *
 * Overview:
 * Type decoders hold a cache of decoded types. Types are read off the wire in
 * defineType() and then lazily converted from partial to defined types when
 * they are needed in lookupType().
 * @private
 */

module.exports = TypeDecoder;

/**
 * Create a TypeDecoder.
 * This holds the set of cached types and assists in decoding.
 * @constructor
 * @private
 */
function TypeDecoder() {
  this._definedTypes = {};
  // Partial types are similar to definedTypes but have type ids for child types
  // rather than fully defined type structures.
  this._partialTypes = {};
}

var kind = require('../vdl/kind.js');
var Type = require('../vdl/type.js');
var BootstrapTypes = require('./bootstrap-types.js');
var RawVomReader = require('./raw-vom-reader.js');
var unwrap = require('../vdl/type-util').unwrap;
var wiretype = require('../gen-vdl/v.io/v23/vom');

var endByte = unwrap(wiretype.WireCtrlEnd);

/**
 * Looks up a type in the decoded types cache by id.
 * @param {number} typeId The type id.
 * @return {Type} The decoded type or undefined.
 */
TypeDecoder.prototype.lookupType = function(typeId) {
  return this._lookupTypeImpl(typeId, true);
};

/**
 * Looks up a type in the decoded types cache by id.
 * @param {number} typeId The type id.
 * @param {boolean} defineUndefined True if partial types that this method
 * resolves to should be built. False otherwise.
 * Partial types should only be built when this is called through lookupType so
 * that they are built lazily.
 * @return {Type} The decoded type or undefined.
 */
TypeDecoder.prototype._lookupTypeImpl = function(typeId, definePartialTypes) {
  if (typeId < 0) {
    throw new Error('invalid negative type id.');
  }

  var type = BootstrapTypes.idToType(typeId);
  if (type !== undefined) {
    return type;
  }

  if (definePartialTypes && this._partialTypes.hasOwnProperty(typeId)) {
    this._tryBuildPartialType(typeId, this._partialTypes[typeId]);
  }

  return this._definedTypes[typeId];
};

/**
 * Add a new type definition to the type cache.
 * @param {number} typeId The id of the type.
 * @param {Uint8Array} The raw bytes that describe the type structure.
 */
TypeDecoder.prototype.defineType = function(typeId, messageBytes) {
  if (typeId < 0) {
    throw new Error('invalid negative type id ' + typeId + '.');
  }
  if (this._definedTypes[typeId] !== undefined ||
    this._partialTypes[typeId] !== undefined) {
    throw new Error('Cannot redefine type with id ' + typeId);
  }

  // Read the type in and add it to the partial type set.
  this._partialTypes[typeId] = this._readPartialType(messageBytes);
};

/**
 * Flattens the type's dependencies into a typeId->(type, partial type) map.
 * @throws Error if the type's dependencies are not available.
 */
TypeDecoder.prototype._flattenTypeDepGraph = function(typeId, typeDeps) {
  // Already in map?
  if (typeDeps[typeId] !== undefined) {
    return;
  }
  // Already defined?
  if (this._lookupTypeImpl(typeId, false) !== undefined) {
    return;
  }
  // Allocate a type for the partial type.
  if (!this._partialTypes.hasOwnProperty(typeId)) {
    throw new Error('Type definition with ID ' + typeId +
      ' not received.');
  }
  var partialType = this._partialTypes[typeId];
  typeDeps[typeId] = {
    partialType: partialType,
    type: new Type()
  };

  // Recurse.
  if (partialType.namedTypeId !== undefined) {
    this._flattenTypeDepGraph(partialType.namedTypeId, typeDeps);
  }
  if (partialType.keyTypeId !== undefined) {
    this._flattenTypeDepGraph(partialType.keyTypeId, typeDeps);
  }
  if (partialType.elemTypeId !== undefined) {
    this._flattenTypeDepGraph(partialType.elemTypeId, typeDeps);
  }
  var i;
  if (partialType.typeIds !== undefined) {
    for (i = 0; i < partialType.typeIds.length; i++) {
      this._flattenTypeDepGraph(partialType.typeIds[i], typeDeps);
    }
  }
  if (partialType.fields !== undefined) {
    for (i = 0; i < partialType.fields.length; i++) {
      this._flattenTypeDepGraph(partialType.fields[i].typeId, typeDeps);
    }
  }
};

/**
 * Tries to build a partial type into a type.
 * This has two steps:
 * 1. Allocate type objects for all dependencies
 * 2. Copy the type and replace the type id with the created types.
 * 3. Copy named types and change the name.
 */
TypeDecoder.prototype._tryBuildPartialType = function(typeId) {
  if (!this._partialTypes.hasOwnProperty(typeId)) {
    throw new Error('Type definition with ID ' + typeId +
      ' not received.');
  }
  var partialType = this._partialTypes[typeId];

  var flattenedTypes = {};
  this._flattenTypeDepGraph(typeId, flattenedTypes);

  var self = this;
  var getType = function(id) {
    var type = self._lookupTypeImpl(id, false);
    if (type !== undefined) {
      return type;
    }
    type = flattenedTypes[id].type;
    if (type !== undefined) {
      return type;
    }
    throw new Error('Type unexpectedly undefined.');
  };

  var id;
  var type;
  var i;
  // All dependencies are ready. Build the type.
  for (id in flattenedTypes) {
    if (!flattenedTypes.hasOwnProperty(id)) {
      continue;
    }
    partialType = flattenedTypes[id].partialType;
    type = flattenedTypes[id].type;

    if (partialType.namedTypeId !== undefined) {
      // Handle named types in a second pass because it involves copying.
      continue;
    }

    type.kind = partialType.kind;
    if (partialType.name !== undefined) {
      type.name = partialType.name;
    }
    if (partialType.labels !== undefined) {
      type.labels = partialType.labels;
    }
    if (partialType.len !== undefined) {
      type.len = partialType.len;
    }

    if (partialType.keyTypeId !== undefined) {
      type.key = getType(partialType.keyTypeId);
    }
    if (partialType.elemTypeId !== undefined) {
      type.elem = getType(partialType.elemTypeId);
    }
    if (partialType.typeIds !== undefined) {
      type.types = new Array(partialType.typeIds.length);
      for (i = 0; i < partialType.typeIds.length; i++) {
        type.types[i] = getType(partialType.typeIds[i]);
      }
    }
    if (partialType.fields !== undefined) {
      type.fields = new Array(partialType.fields.length);
      for (i = 0; i < partialType.fields.length; i++) {
        var partialField = partialType.fields[i];
        type.fields[i] = {
          name: partialField.name,
          type: getType(partialField.typeId)
        };
      }
    }
  }

  // Now handle named types.
  for (id in flattenedTypes) {
    if (flattenedTypes.hasOwnProperty(id)) {
      partialType = flattenedTypes[id].partialType;
      type = flattenedTypes[id].type;

      if (partialType.namedTypeId !== undefined) {
        // Special case for named types.
        var toCopy = getType(partialType.namedTypeId);
        for (var fieldName in toCopy) {
          if (toCopy.hasOwnProperty(fieldName)) {
            type[fieldName] = toCopy[fieldName];
          }
        }
        type.name = partialType.name;
      }
    }
  }

  // Now that the types are all prepared, make them immutable.
  for (id in flattenedTypes) {
    if (flattenedTypes.hasOwnProperty(id)) {
      type = flattenedTypes[id].type;

      // Make the type immutable, setting its _unique string too.
      type.freeze();

      // Define the type.
      this._definedTypes[id] = type;

      // Remove the type from the partial type set.
      delete this._partialTypes[id];
    }
  }
};

/**
 * Read the binary type description into a partial type description.
 * @param {Uint8Array} messageBytes The binary type message.
 * @return {PartialType} The type that was read.
 */
TypeDecoder.prototype._readPartialType = function(messageBytes) {
  var reader = new RawVomReader(messageBytes);
  var unionId = reader.readUint();
  var partialType = {};
  var nextIndex;
  var i;
  switch (unionId) {
    case BootstrapTypes.unionIds.NAMED_TYPE:
      endDef:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.namedTypeId = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireNamed: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.ENUM_TYPE:
      partialType.kind = kind.ENUM;
      endDef2:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef2;
        }

        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.labels = new Array(reader.readUint());
            for (i = 0; i < partialType.labels.length; i++) {
              partialType.labels[i] = reader.readString();
            }
            break;
          default:
            throw new Error('Unexpected index for WireEnum: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.ARRAY_TYPE:
      partialType.kind = kind.ARRAY;
      endDef3:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef3;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.elemTypeId = reader.readUint();
            break;
          case 2:
            partialType.len = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireArray: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.LIST_TYPE:
      partialType.kind = kind.LIST;
      endDef4:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef4;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.elemTypeId = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireList: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.SET_TYPE:
      partialType.kind = kind.SET;
      endDef5:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef5;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.keyTypeId = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireSet: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.MAP_TYPE:
      partialType.kind = kind.MAP;
      endDef6:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef6;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.keyTypeId = reader.readUint();
            break;
          case 2:
            partialType.elemTypeId = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireMap: ' + nextIndex);
          }
      }
      break;
    case BootstrapTypes.unionIds.STRUCT_TYPE:
    case BootstrapTypes.unionIds.UNION_TYPE:
      if (unionId === BootstrapTypes.unionIds.STRUCT_TYPE) {
        partialType.kind = kind.STRUCT;
      } else {
        partialType.kind = kind.UNION;
      }
      endDef7:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef7;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.fields = new Array(reader.readUint());
            for (i = 0; i < partialType.fields.length; i++) {
              partialType.fields[i] = {};
              sfEndDef:
              while(true) {
                if (reader.tryReadControlByte() === endByte) {
                  break sfEndDef;
                }
                var sfNextIndex = reader.readUint();
                switch(sfNextIndex) {
                  case 0:
                    var s = reader.readString();
                    partialType.fields[i].name = s;
                    break;
                  case 1:
                    partialType.fields[i].typeId = reader.readUint();
                    break;
                }
              }
            }
            break;
          default:
            throw new Error('Unexpected index for WireStruct: ' + nextIndex);
          }
      }
      // We allow struct{} definitions.
      if (partialType.kind === kind.STRUCT) {
        partialType.fields = partialType.fields || [];
      }
      break;
    case BootstrapTypes.unionIds.OPTIONAL_TYPE:
      partialType.kind = kind.OPTIONAL;
      endDef9:
      while (true) {
        if (reader.tryReadControlByte() === endByte) {
          break endDef9;
        }
        nextIndex = reader.readUint();
        switch(nextIndex) {
          case 0:
            partialType.name = reader.readString();
            break;
          case 1:
            partialType.elemTypeId = reader.readUint();
            break;
          default:
            throw new Error('Unexpected index for WireOptional: ' + nextIndex);
          }
      }
      break;
    default:
      throw new Error('Unknown wire type id ' + unionId);
  }
  partialType.name = partialType.name || '';
  return partialType;
};
