"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _writableTrackingBuffer = _interopRequireDefault(require("./tracking-buffer/writable-tracking-buffer"));
var _allHeaders = require("./all-headers");
var _errors = require("./errors");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// const OPTION = {
//   WITH_RECOMPILE: 0x01,
//   NO_METADATA: 0x02,
//   REUSE_METADATA: 0x04
// };

const STATUS = {
  BY_REF_VALUE: 0x01,
  DEFAULT_VALUE: 0x02
};

/*
  s2.2.6.5
 */
class RpcRequestPayload {
  constructor(procedure, parameters, txnDescriptor, options, collation) {
    this.procedure = procedure;
    this.parameters = parameters;
    this.options = options;
    this.txnDescriptor = txnDescriptor;
    this.collation = collation;
  }
  [Symbol.iterator]() {
    return this.generateData();
  }
  *generateData() {
    const buffer = new _writableTrackingBuffer.default(500);
    if (this.options.tdsVersion >= '7_2') {
      const outstandingRequestCount = 1;
      (0, _allHeaders.writeToTrackingBuffer)(buffer, this.txnDescriptor, outstandingRequestCount);
    }
    if (typeof this.procedure === 'string') {
      buffer.writeUsVarchar(this.procedure);
    } else {
      buffer.writeUShort(0xFFFF);
      buffer.writeUShort(this.procedure);
    }
    const optionFlags = 0;
    buffer.writeUInt16LE(optionFlags);
    yield buffer.data;
    const parametersLength = this.parameters.length;
    for (let i = 0; i < parametersLength; i++) {
      yield* this.generateParameterData(this.parameters[i]);
    }
  }
  toString(indent = '') {
    return indent + ('RPC Request - ' + this.procedure);
  }
  *generateParameterData(parameter) {
    const buffer = new _writableTrackingBuffer.default(1 + 2 + Buffer.byteLength(parameter.name, 'ucs-2') + 1);
    if (parameter.name) {
      buffer.writeBVarchar('@' + parameter.name);
    } else {
      buffer.writeBVarchar('');
    }
    let statusFlags = 0;
    if (parameter.output) {
      statusFlags |= STATUS.BY_REF_VALUE;
    }
    buffer.writeUInt8(statusFlags);
    yield buffer.data;
    const param = {
      value: parameter.value
    };
    const type = parameter.type;
    if ((type.id & 0x30) === 0x20) {
      if (parameter.length) {
        param.length = parameter.length;
      } else if (type.resolveLength) {
        param.length = type.resolveLength(parameter);
      }
    }
    if (parameter.precision) {
      param.precision = parameter.precision;
    } else if (type.resolvePrecision) {
      param.precision = type.resolvePrecision(parameter);
    }
    if (parameter.scale) {
      param.scale = parameter.scale;
    } else if (type.resolveScale) {
      param.scale = type.resolveScale(parameter);
    }
    if (this.collation) {
      param.collation = this.collation;
    }
    yield type.generateTypeInfo(param, this.options);
    yield type.generateParameterLength(param, this.options);
    try {
      yield* type.generateParameterData(param, this.options);
    } catch (error) {
      throw new _errors.InputError(`Input parameter '${parameter.name}' could not be validated`, {
        cause: error
      });
    }
  }
}
var _default = exports.default = RpcRequestPayload;
module.exports = RpcRequestPayload;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 10448 characters]