// Generated by CoffeeScript 1.7.1
var TYPE, codepageByLcid, parse, sprintf;

codepageByLcid = require('./collation').codepageByLcid;

TYPE = require('./data-type').TYPE;

sprintf = require('sprintf').sprintf;

parse = function(buffer, options) {
  var collation, collationData, dataLength, flags, metadata, precision, scale, schema, schemaPresent, type, typeNumber, udtInfo, userType;
  if (options.tdsVersion < "7_2") {
    userType = buffer.readUInt16LE();
  } else {
    userType = buffer.readUInt32LE();
  }
  flags = buffer.readUInt16LE();
  typeNumber = buffer.readUInt8();
  type = TYPE[typeNumber];
  if (!type) {
    throw new Error(sprintf('Unrecognised data type 0x%02X at offset 0x%04X', typeNumber, buffer.position - 1));
  }
  if ((type.id & 0x30) === 0x20) {
    switch (type.dataLengthLength) {
      case 0:
        dataLength = void 0;
        break;
      case 1:
        dataLength = buffer.readUInt8();
        break;
      case 2:
        dataLength = buffer.readUInt16LE();
        break;
      case 4:
        dataLength = buffer.readUInt32LE();
        break;
      default:
        throw new Error("Unsupported dataLengthLength " + type.dataLengthLength + " for data type " + type.name);
    }
  } else {
    dataLength = void 0;
  }
  if (type.hasPrecision) {
    precision = buffer.readUInt8();
  } else {
    precision = void 0;
  }
  if (type.hasScale) {
    scale = buffer.readUInt8();
    if (type.dataLengthFromScale) {
      dataLength = type.dataLengthFromScale(scale);
    }
  } else {
    scale = void 0;
  }
  if (type.hasCollation) {
    collationData = buffer.readBuffer(5);
    collation = {};
    collation.lcid = (collationData[2] & 0x0F) << 16;
    collation.lcid |= collationData[1] << 8;
    collation.lcid |= collationData[0];
    collation.codepage = codepageByLcid[collation.lcid];
    collation.flags = collationData[3] >> 4;
    collation.flags |= collationData[2] & 0xF0;
    collation.version = collationData[3] & 0x0F;
    collation.sortId = collationData[4];
  } else {
    collation = void 0;
  }
  schema = void 0;
  if (type.hasSchemaPresent) {
    schemaPresent = buffer.readUInt8();
    if (schemaPresent === 0x01) {
      schema = {
        dbname: buffer.readBVarchar(),
        owningSchema: buffer.readBVarchar(),
        xmlSchemaCollection: buffer.readUsVarchar()
      };
    }
  }
  udtInfo = void 0;
  if (type.hasUDTInfo) {
    udtInfo = {
      maxByteSize: buffer.readUInt16LE(),
      dbname: buffer.readBVarchar(),
      owningSchema: buffer.readBVarchar(),
      typeName: buffer.readBVarchar(),
      assemblyName: buffer.readUsVarchar()
    };
  }
  return metadata = {
    userType: userType,
    flags: flags,
    type: type,
    collation: collation,
    precision: precision,
    scale: scale,
    dataLength: dataLength,
    schema: schema,
    udtInfo: udtInfo
  };
};

module.exports = parse;
