/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
var Thrift = {

    Type : {
        "STOP"   : 0,
        "VOID"   : 1,
        "BOOL"   : 2,
        "BYTE"   : 3,
        "I08"    : 3,
        "DOUBLE" : 4,
        "I16"    : 6,
        "I32"    : 8,
        "I64"    : 10,
        "STRING" : 11,
        "UTF7"   : 11,
        "STRUCT" : 12,
        "MAP"    : 13,
        "SET"    : 14,
        "LIST"   : 15,
        "UTF8"   : 16,
        "UTF16"  : 17
    },

    MessageType : {
        "CALL"      : 1,
        "REPLY"     : 2,
        "EXCEPTION" : 3
    }
}

Thrift.TException = {}
Thrift.TException.prototype = { 
    initialize: function( message, code ) {
            this.message = message;
            this.code    = (code == null) ? 0 : code;
    }
}


Thrift.TApplicationExceptionType = {
    "UNKNOWN"              : 0,
    "UNKNOWN_METHOD"       : 1,
    "INVALID_MESSAGE_TYPE" : 2,
    "WRONG_METHOD_NAME"    : 3,
    "BAD_SEQUENCE_ID"      : 4,
    "MISSING_RESULT"       : 5       
}

Thrift.TApplicationException = function(message, code){
    this.message = message
    this.code    = (code == null) ? 0 : code
}

Thrift.TApplicationException.prototype = { 
       
    read : function(input){
        
        var ftype
        var fid
        var ret = input.readStructBegin(fname) 
        
        this.fname = ret.fname      
        
        while(1){
            
            ret = input.readFieldBegin()
            
            if(ret.ftype == TType.STOP)
                break
            
            var fid = ret.fid
            
            switch(fid){
                case 1: 
                    if( ret.ftype == Type.STRING ){
                        ret = input.readString()
                        this.message = ret.value
                    } else {
                        ret = input.skip(ret.ftype)
                    }
                    
                    break
                case 2:
                    if( ret.ftype == Type.I32 ){
                        ret = input.readI32()
                        this.code = ret.value
                    } else {
                        ret   = input.skip(ret.ftype)
                    }
                    break
                    
                default:
                    ret = input.skip(ret.ftype)
                    break
            }
            
            input.readFieldEnd()
            
        }
        
        input.readStructEnd()
        
    },
    
    write: function(output){
        var xfer   = 0;
        
        output.writeStructBegin('TApplicationException');
        
        if (this.message) {
            output.writeFieldBegin('message', Type.STRING, 1)
            output.writeString(this.getMessage())
            output.writeFieldEnd()
        }
        
        if (this.code) {
            output.writeFieldBegin('type', Type.I32, 2)
            output.writeI32(this.code)
            output.writeFieldEnd()
        }
        
        output.writeFieldStop()
        output.writeStructEnd()
       
    },
    
    getCode : function() {
        return this.code
    },
    
    getMessage : function() {
        return this.message
    }
}



/**
 *If you do not specify a url then you must handle ajax on your own.
 *This is how to use js bindings in a async fashion.
 */
Thrift.Transport = function(url){
    this.url      = url
    this.wpos     = 0
    this.rpos     = 0

    this.send_buf = ''
    this.recv_buf = ''
}

Thrift.Transport.prototype = {

    //Gets the browser specific XmlHttpRequest Object
    getXmlHttpRequestObject : function() {
    
        try { return new XMLHttpRequest() } catch(e) {}
        try { return new ActiveXObject("Msxml2.XMLHTTP") } catch (e) {}
        try { return new ActiveXObject("Microsoft.XMLHTTP") } catch (e) {}

        throw "Your browser doesn't support the XmlHttpRequest object.  Try upgrading to Firefox."
    
    },

    flush : function(){

        //async mode
        if(this.url == undefined || this.url == '')
            return this.send_buf;

        var xreq = this.getXmlHttpRequestObject()
                
        if (xreq.overrideMimeType)
            xreq.overrideMimeType("application/json")
        
        xreq.open("POST", this.url, false)
        xreq.send(this.send_buf)
        
        if (xreq.readyState != 4)
            throw "encountered an unknown ajax ready state: "+xreq.readyState
        
        if (xreq.status != 200)
            throw "encountered a unknown request status: "+xreq.status

        this.recv_buf    = xreq.responseText
        this.recv_buf_sz = this.recv_buf.length
        this.wpos        = this.recv_buf.length
        this.rpos        = 0
    },

    setRecvBuffer : function(buf){
        this.recv_buf    = buf
        this.recv_buf_sz = this.recv_buf.length
        this.wpos        = this.recv_buf.length
        this.rpos        = 0
    },

    isOpen : function() {
        return true
    },

    open : function() {},

    close: function() {},

    read : function(len) {
        var avail = this.wpos - this.rpos
       
        if(avail == 0)
            return ''

        var give = len

        if(avail < len)
            give = avail

        var ret = this.read_buf.substr(this.rpos,give)
        this.rpos += give

        //clear buf when complete?
        return ret
    },

    readAll : function() {
       return this.recv_buf
    },

    write : function(buf){
        this.send_buf = buf
    },

    getSendBuffer : function(){
        return this.send_buf
    }

}



Thrift.Protocol = function(transport){
    this.transport = transport
}

Thrift.Protocol.Type = {}
Thrift.Protocol.Type[ Thrift.Type.BOOL   ] = '"tf"'
Thrift.Protocol.Type[ Thrift.Type.BYTE   ] = '"i8"'
Thrift.Protocol.Type[ Thrift.Type.I16    ] = '"i16"'
Thrift.Protocol.Type[ Thrift.Type.I32    ] = '"i32"'
Thrift.Protocol.Type[ Thrift.Type.I64    ] = '"i64"'
Thrift.Protocol.Type[ Thrift.Type.DOUBLE ] = '"dbl"'
Thrift.Protocol.Type[ Thrift.Type.STRUCT ] = '"rec"'
Thrift.Protocol.Type[ Thrift.Type.STRING ] = '"str"'
Thrift.Protocol.Type[ Thrift.Type.MAP    ] = '"map"'
Thrift.Protocol.Type[ Thrift.Type.LIST   ] = '"lst"'
Thrift.Protocol.Type[ Thrift.Type.SET    ] = '"set"'


Thrift.Protocol.RType = {}
Thrift.Protocol.RType[ "tf" ] = Thrift.Type.BOOL
Thrift.Protocol.RType[ "i8" ] = Thrift.Type.BYTE
Thrift.Protocol.RType[ "i16"] = Thrift.Type.I16
Thrift.Protocol.RType[ "i32"] = Thrift.Type.I32
Thrift.Protocol.RType[ "i64"] = Thrift.Type.I64 
Thrift.Protocol.RType[ "dbl"] = Thrift.Type.DOUBLE 
Thrift.Protocol.RType[ "rec"] = Thrift.Type.STRUCT 
Thrift.Protocol.RType[ "str"] = Thrift.Type.STRING
Thrift.Protocol.RType[ "map"] = Thrift.Type.MAP 
Thrift.Protocol.RType[ "lst"] = Thrift.Type.LIST
Thrift.Protocol.RType[ "set"] = Thrift.Type.SET 

Thrift.Protocol.Version = 1

Thrift.Protocol.prototype = {
    
    getTransport : function(){
        return this.transport
    },

    //Write functions
    writeMessageBegin : function(name,messageType,seqid){
        this.tstack = new Array()
        this.tpos   = new Array();
           
        this.tstack.push([Thrift.Protocol.Version,'"'+name+'"',messageType,seqid]);
    },

    writeMessageEnd : function(){
        var obj = this.tstack.pop()
        
        this.wobj = this.tstack.pop()
        this.wobj.push(obj)
 
        this.wbuf = "["+this.wobj.join(",")+"]";

        this.transport.write(this.wbuf);       
     },


    writeStructBegin : function(name){
        this.tpos.push(this.tstack.length)
        this.tstack.push({})
    },

    writeStructEnd : function(){
        
        var p = this.tpos.pop()
        var struct = this.tstack[p]
        var str = "{"
        var first = true
        for( var key in struct ){
            if(first) 
                first = false;
            else
                str += ",";

            str += key+":"+struct[key]
        } 

        str += "}"
        this.tstack[p] = str;
    },

    writeFieldBegin : function(name,fieldType,fieldId){
        this.tpos.push(this.tstack.length)
        this.tstack.push({"fieldId" : '"'+fieldId+'"', "fieldType" : Thrift.Protocol.Type[fieldType]});
       
    },

    writeFieldEnd : function(){
        var value     = this.tstack.pop()
        var fieldInfo = this.tstack.pop() 
        
        this.tstack[this.tstack.length-1][fieldInfo.fieldId] = "{"+fieldInfo.fieldType+":"+value+"}" 
        this.tpos.pop()
    },

    writeFieldStop : function(){
        //na
    },

    writeMapBegin : function(keyType,valType,size){
        //size is invalid, we'll set it on end.
        this.tpos.push(this.tstack.length)
        this.tstack.push([Thrift.Protocol.Type[keyType],Thrift.Protocol.Type[valType],0]) 
    },

    writeMapEnd : function(){
        var p   = this.tpos.pop()
        
        if(p == this.tstack.length)
            return;
        
        if((this.tstack.length - p - 1) % 2 != 0)
            this.tstack.push("");

        var size = (this.tstack.length - p - 1)/2

        this.tstack[p][this.tstack[p].length-1] = size;
        
        var map   = "{"
        var first = true
        while( this.tstack.length > p+1 ){
            var v = this.tstack.pop()
            var k = this.tstack.pop()
            if(first){
                first = false
            }else{
                map += ","
            }
            
            map  += '"'+k+'":'+v
        }
        map += "}"
        
        this.tstack[p].push(map)
        this.tstack[p] = "["+this.tstack[p].join(",")+"]"
    },

    writeListBegin : function(elemType,size){
        this.tpos.push(this.tstack.length)
        this.tstack.push([Thrift.Protocol.Type[elemType],size]);
    },

    writeListEnd : function(){
        var p = this.tpos.pop()

        while( this.tstack.length > p+1 ){
            var tmpVal = this.tstack[p+1]
            this.tstack.splice(p+1, 1)
            this.tstack[p].push(tmpVal)
        }

        this.tstack[p] = '['+this.tstack[p].join(",")+']';
    },

    writeSetBegin : function(elemType,size){
        this.tpos.push(this.tstack.length)
        this.tstack.push([Thrift.Protocol.Type[elemType],size]);
    },

    writeSetEnd : function(){
        var p = this.tpos.pop()

        while( this.tstack.length > p+1 ){
            var tmpVal = this.tstack[p+1]
            this.tstack.splice(p+1, 1)
            this.tstack[p].push(tmpVal)
        }

        this.tstack[p] = '['+this.tstack[p].join(",")+']';
    },

    writeBool : function(value){
        this.tstack.push( value ? 1 : 0 );
    },

    writeByte : function(i8){
        this.tstack.push(i8);
    },

    writeI16 : function(i16){
        this.tstack.push(i16);
    },

    writeI32 : function(i32){
        this.tstack.push(i32);
    },

    writeI64 : function(i64){
        this.tstack.push(i64);
    },

    writeDouble : function(dbl){
        this.tstack.push(dbl);
    },

    writeString : function(str){
        // We do not encode uri components for wire transfer: 
        if(str === null) {
            this.tstack.push(null);
        } else {
            // concat may be slower than building a byte buffer
            var escapedString = "";
            for(var i = 0; i < str.length; i++) {
                var ch = str.charAt(i);          // a single double quote: "
                if(ch === '\"') {
                    escapedString += '\\\"';     // write out as: \"
                } else if(ch === '\\') {         // a single backslash: \
                    escapedString += '\\\\';     // write out as: \\
                /* Currently escaped forward slashes break TJSONProtocol.
                 * As it stands, we can simply pass forward slashes into our strings
                 * across the wire without being escaped.
                 * I think this is the protocol's bug, not thrift.js
                 * } else if(ch === '/') {       // a single forward slash: /
                 *  escapedString += '\\/';      // write out as \/
                 * } 
                 */
                } else if(ch === '\b') {        // a single backspace: invisible
                    escapedString += '\\b';     // write out as: \b"
                } else if(ch === '\f') {        // a single formfeed: invisible
                    escapedString += '\\f';     // write out as: \f"
                } else if(ch === '\n') {        // a single newline: invisible
                    escapedString += '\\n';     // write out as: \n"
                } else if(ch === '\r') {        // a single return: invisible
                    escapedString += '\\r';     // write out as: \r"
                } else if(ch === '\t') {        // a single tab: invisible
                    escapedString += '\\t';     // write out as: \t"
                } else {
                    escapedString += ch;        // Else it need not be escaped
                }
            }
            this.tstack.push('"' + escapedString + '"');
        }
    },

    writeBinary : function(str){
        this.writeString(str);
    },


    
    // Reading functions
    readMessageBegin : function(name, messageType, seqid){
        this.rstack = new Array()
        this.rpos   = new Array()
       
        this.robj = eval(this.transport.readAll())
        
        var r = {}     
        var version = this.robj.shift()
        
        if(version != Thrift.Protocol.Version){
            throw "Wrong thrift protocol version: "+version
        }

        r["fname"]  = this.robj.shift()
        r["mtype"]  = this.robj.shift()
        r["rseqid"] = this.robj.shift()
        
        
        //get to the main obj
        this.rstack.push(this.robj.shift())
      
        return r
    },

  
    readMessageEnd : function(){
    },

    readStructBegin : function(name){
        var r = {}
        r["fname"] = ''
        
        //incase this is an array of structs
        if(this.rstack[this.rstack.length-1] instanceof Array)
            this.rstack.push(this.rstack[this.rstack.length-1].shift())
     
        return r
    },

    readStructEnd : function(){
        if(this.rstack[this.rstack.length-2] instanceof Array)
            this.rstack.pop()
    },

    readFieldBegin : function(){
        var r = {};
        
        var fid   = -1
        var ftype = Thrift.Type.STOP 
        
        //get a fieldId
        for(var f in (this.rstack[this.rstack.length-1])){
            if(f == null) continue
            
            fid = parseInt(f)
            this.rpos.push(this.rstack.length)
            
            var field = this.rstack[this.rstack.length-1][fid]
           
            //remove so we don't see it again
            delete this.rstack[this.rstack.length-1][fid]
            
            this.rstack.push(field)            
            
            break
        }
            
        if(fid != -1){      
       
            //should only be 1 of these but this is the only
            //way to match a key
            for(var f in (this.rstack[this.rstack.length-1])){
                if(Thrift.Protocol.RType[f] == null ) continue
                
                ftype = Thrift.Protocol.RType[f]
                this.rstack[this.rstack.length-1] = this.rstack[this.rstack.length-1][f]
            }        
        }
        
        r["fname"] = ''
        r["ftype"] = ftype
        r["fid"]   = fid
        

        return r
    },

    readFieldEnd : function(){  
        var pos = this.rpos.pop()
        
        //get back to the right place in the stack
        while(this.rstack.length > pos)
            this.rstack.pop();
                 
    },

    readMapBegin : function(keyType,valType,size){
        
        var map = this.rstack.pop()
        
        var r = {};
        r["ktype"] = Thrift.Protocol.RType[map.shift()]
        r["vtype"] = Thrift.Protocol.RType[map.shift()]
        r["size"]  = map.shift()
        
        
        this.rpos.push(this.rstack.length)
        this.rstack.push(map.shift())
        
        return r;
    },

    readMapEnd : function(){
        this.readFieldEnd()
    },

    readListBegin : function(elemType,size){
      
        var list = this.rstack[this.rstack.length-1]
      
        var r = {};
        r["etype"] = Thrift.Protocol.RType[list.shift()];
        r["size" ] = list.shift();
        
        
        this.rpos.push(this.rstack.length);
        this.rstack.push(list)
             
        return r;
    },

    readListEnd : function(){
        this.readFieldEnd()
    },

    readSetBegin : function(elemType,size){
        return this.readListBegin(elemType,size)
    },

    readSetEnd : function(){
        return this.readListEnd()
    },

    readBool : function(){
        var r = this.readI32()
    
        if( r != null && r["value"] == "1" ){
            r["value"] = true
        }else{
            r["value"] = false
        }
        
        return r
    },

    readByte : function(){
        return this.readI32()
    },

    readI16 : function(){
        return this.readI32()
    },
   

    readI32 : function(f){
        if(f == undefined)
            f = this.rstack[this.rstack.length-1]
        
        var r = {}    
            
        if(f instanceof Array){
            if(f.length == 0)
                r["value"] = undefined
            else
                r["value"] = f.shift()

        }else if(f instanceof Object){
           for(var i in f){
                if(i == null) continue
                this.rstack.push(f[i])
                delete f[i]  
                                  
                r["value"] = i
                break
           }
        } else {
            r["value"] = f
        }
        
        return r
    },

    readI64 : function(){
        return this.readI32()
    },

    readDouble : function(){
        return this.readI32()
    },

    readString : function(){
        var r = this.readI32()
        return r
    },

    readBinary : function(){
        return this.readString()
    },

    
    //Method to arbitrarily skip over data.
    skip : function(type){
        throw "skip not supported yet"
    }
   
}

Thrift.objectLength = function(obj) {
  var length = 0;
  for (k in obj) {
    if (obj.hasOwnProperty(k)) {
      length++;
    }
  }
  return length;
}


