var Stream=require("stream").Stream,util=require("util"),driver=require("websocket-driver"),Headers=require("websocket-driver/lib/websocket/driver/headers"),API=require("./websocket/api"),EventTarget=require("./websocket/api/event_target"),Event=require("./websocket/api/event"),EventSource=function(e,t,r){this.writable=!0,r=r||{},this._stream=t.socket,this._ping=r.ping||this.DEFAULT_PING,this._retry=r.retry||this.DEFAULT_RETRY;var i=driver.isSecureRequest(e)?"https:":"http:";this.url=i+"//"+e.headers.host+e.url,this.lastEventId=e.headers["last-event-id"]||"",this.readyState=API.CONNECTING;var n=new Headers,s=this;if(r.headers)for(var a in r.headers)n.set(a,r.headers[a]);if(this._stream&&this._stream.writable){process.nextTick(function(){s._open()}),this._stream.setTimeout(0),this._stream.setNoDelay(!0);var o="HTTP/1.1 200 OK\r\nContent-Type: text/event-stream\r\nCache-Control: no-cache, no-store\r\nConnection: close\r\n"+n.toString()+"\r\nretry: "+Math.floor(1e3*this._retry)+"\r\n\r\n";this._write(o),this._stream.on("drain",function(){s.emit("drain")}),this._ping&&(this._pingTimer=setInterval(function(){s.ping()},1e3*this._ping)),["error","end"].forEach(function(e){s._stream.on(e,function(){s.close()})})}};util.inherits(EventSource,Stream),EventSource.isEventSource=function(e){return"GET"===e.method&&(e.headers.accept||"").split(/\s*,\s*/).indexOf("text/event-stream")>=0};var instance={DEFAULT_PING:10,DEFAULT_RETRY:5,_write:function(e){if(!this.writable)return!1;try{return this._stream.write(e,"utf8")}catch(e){return!1}},_open:function(){if(this.readyState===API.CONNECTING){this.readyState=API.OPEN;var e=new Event("open");e.initEvent("open",!1,!1),this.dispatchEvent(e)}},write:function(e){return this.send(e)},end:function(e){void 0!==e&&this.write(e),this.close()},send:function(e,t){if(this.readyState>API.OPEN)return!1;e=String(e).replace(/(\r\n|\r|\n)/g,"$1data: ");var r="";return(t=t||{}).event&&(r+="event: "+t.event+"\r\n"),t.id&&(r+="id: "+t.id+"\r\n"),r+="data: "+e+"\r\n\r\n",this._write(r)},ping:function(){return this._write(":\r\n\r\n")},close:function(){if(this.readyState>API.OPEN)return!1;this.readyState=API.CLOSED,this.writable=!1,this._pingTimer&&clearInterval(this._pingTimer),this._stream&&this._stream.end();var e=new Event("close");return e.initEvent("close",!1,!1),this.dispatchEvent(e),!0}};for(var method in instance)EventSource.prototype[method]=instance[method];for(var key in EventTarget)EventSource.prototype[key]=EventTarget[key];module.exports=EventSource;