"use strict";var Parser=require("./parser"),Pipeline=require("./pipeline"),Extensions=function(){this._rsv1=this._rsv2=this._rsv3=null,this._byName={},this._inOrder=[],this._sessions=[],this._index={}};Extensions.MESSAGE_OPCODES=[1,2];var instance={add:function(e){if("string"!=typeof e.name)throw new TypeError("extension.name must be a string");if("permessage"!==e.type)throw new TypeError('extension.type must be "permessage"');if("boolean"!=typeof e.rsv1)throw new TypeError("extension.rsv1 must be true or false");if("boolean"!=typeof e.rsv2)throw new TypeError("extension.rsv2 must be true or false");if("boolean"!=typeof e.rsv3)throw new TypeError("extension.rsv3 must be true or false");if(this._byName.hasOwnProperty(e.name))throw new TypeError('An extension with name "'+e.name+'" is already registered');this._byName[e.name]=e,this._inOrder.push(e)},generateOffer:function(){var e=[],s=[],r={};return this._inOrder.forEach(function(n){var i=n.createClientSession();if(i){var t=[n,i];e.push(t),r[n.name]=t;var o=i.generateOffer();(o=o?[].concat(o):[]).forEach(function(e){s.push(Parser.serializeParams(n.name,e))},this)}},this),this._sessions=e,this._index=r,s.length>0?s.join(", "):null},activate:function(e){var s=[];Parser.parseHeader(e).eachOffer(function(e,r){var n=this._index[e];if(!n)throw new Error('Server sent an extension response for unknown extension "'+e+'"');var i=n[0],t=n[1],o=this._reserved(i);if(o)throw new Error("Server sent two extension responses that use the RSV"+o[0]+' bit: "'+o[1]+'" and "'+i.name+'"');if(!0!==t.activate(r))throw new Error("Server sent unacceptable extension parameters: "+Parser.serializeParams(e,r));this._reserve(i),s.push(n)},this),this._sessions=s,this._pipeline=new Pipeline(s)},generateResponse:function(e){var s=[],r=[],n=Parser.parseHeader(e);return this._inOrder.forEach(function(e){var i=n.byName(e.name);if(0!==i.length&&!this._reserved(e)){var t=e.createServerSession(i);t&&(this._reserve(e),s.push([e,t]),r.push(Parser.serializeParams(e.name,t.generateResponse())))}},this),this._sessions=s,this._pipeline=new Pipeline(s),r.length>0?r.join(", "):null},validFrameRsv:function(e){var s,r={rsv1:!1,rsv2:!1,rsv3:!1};if(Extensions.MESSAGE_OPCODES.indexOf(e.opcode)>=0)for(var n=0,i=this._sessions.length;n<i;n++)s=this._sessions[n][0],r.rsv1=r.rsv1||s.rsv1,r.rsv2=r.rsv2||s.rsv2,r.rsv3=r.rsv3||s.rsv3;return(r.rsv1||!e.rsv1)&&(r.rsv2||!e.rsv2)&&(r.rsv3||!e.rsv3)},processIncomingMessage:function(e,s,r){this._pipeline.processIncomingMessage(e,s,r)},processOutgoingMessage:function(e,s,r){this._pipeline.processOutgoingMessage(e,s,r)},close:function(e,s){if(!this._pipeline)return e.call(s);this._pipeline.close(e,s)},_reserve:function(e){this._rsv1=this._rsv1||e.rsv1&&e.name,this._rsv2=this._rsv2||e.rsv2&&e.name,this._rsv3=this._rsv3||e.rsv3&&e.name},_reserved:function(e){return this._rsv1&&e.rsv1?[1,this._rsv1]:this._rsv2&&e.rsv2?[2,this._rsv2]:!(!this._rsv3||!e.rsv3)&&[3,this._rsv3]}};for(var key in instance)Extensions.prototype[key]=instance[key];module.exports=Extensions;