/*
 * 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.
 */

declare module Thrift {
  /**
   * Thrift JavaScript library version.
   */
  var Version: string;

  /**
   * Thrift IDL type string to Id mapping.
   * @property {number}  STOP   - End of a set of fields.
   * @property {number}  VOID   - No value (only legal for return types).
   * @property {number}  BOOL   - True/False integer.
   * @property {number}  BYTE   - Signed 8 bit integer.
   * @property {number}  I08    - Signed 8 bit integer.     
   * @property {number}  DOUBLE - 64 bit IEEE 854 floating point.
   * @property {number}  I16    - Signed 16 bit integer.
   * @property {number}  I32    - Signed 32 bit integer.
   * @property {number}  I64    - Signed 64 bit integer.
   * @property {number}  STRING - Array of bytes representing a string of characters.
   * @property {number}  UTF7   - Array of bytes representing a string of UTF7 encoded characters.
   * @property {number}  STRUCT - A multifield type.
   * @property {number}  MAP    - A collection type (map/associative-array/dictionary).
   * @property {number}  SET    - A collection type (unordered and without repeated values).
   * @property {number}  LIST   - A collection type (unordered).
   * @property {number}  UTF8   - Array of bytes representing a string of UTF8 encoded characters.
   * @property {number}  UTF16  - Array of bytes representing a string of UTF16 encoded characters.
   */
  interface Type {
    'STOP': number;
    'VOID': number;
    'BOOL': number;
    'BYTE': number;
    'I08': number;
    'DOUBLE': number;
    'I16': number;
    'I32': number;
    'I64': number;
    'STRING': number;
    'UTF7': number;
    'STRUCT': number;
    'MAP': number;
    'SET': number;
    'LIST': number;
    'UTF8': number;
    'UTF16': number;
  }
  var Type: Type;

  /**
   * Thrift RPC message type string to Id mapping.
   * @property {number}  CALL      - RPC call sent from client to server.
   * @property {number}  REPLY     - RPC call normal response from server to client.
   * @property {number}  EXCEPTION - RPC call exception response from server to client.
   * @property {number}  ONEWAY    - Oneway RPC call from client to server with no response.
   */
  interface MessageType {
    'CALL': number;
    'REPLY': number;
    'EXCEPTION': number;
    'ONEWAY': number;
  }
  var MessageType: MessageType;

  /**
   * Utility function returning the count of an object's own properties.
   * @param {object} obj - Object to test.
   * @returns {number} number of object's own properties
   */
  function objectLength(obj: any): number;

  /**
   * Utility function to establish prototype inheritance.
   * @param {function} constructor - Contstructor function to set as derived.
   * @param {function} superConstructor - Contstructor function to set as base.
   * @param {string} [name] - Type name to set as name property in derived prototype.
   */
  function inherits(constructor: Function, superConstructor: Function, name?: string): void;

  /**
   * TException is the base class for all Thrift exceptions types.
   */
  class TException implements Error {
    name: string;
    message: string;

    /**
     * Initializes a Thrift TException instance.
     * @param {string} message - The TException message (distinct from the Error message).
     */
    constructor(message: string);

    /**
     * Returns the message set on the exception.
     * @returns {string} exception message
     */
    getMessage(): string;
  }

  /**
   * Thrift Application Exception type string to Id mapping.
   * @property {number}  UNKNOWN                 - Unknown/undefined.
   * @property {number}  UNKNOWN_METHOD          - Client attempted to call a method unknown to the server.
   * @property {number}  INVALID_MESSAGE_TYPE    - Client passed an unknown/unsupported MessageType.
   * @property {number}  WRONG_METHOD_NAME       - Unused.
   * @property {number}  BAD_SEQUENCE_ID         - Unused in Thrift RPC, used to flag proprietary sequence number errors.
   * @property {number}  MISSING_RESULT          - Raised by a server processor if a handler fails to supply the required return result.
   * @property {number}  INTERNAL_ERROR          - Something bad happened.
   * @property {number}  PROTOCOL_ERROR          - The protocol layer failed to serialize or deserialize data.
   * @property {number}  INVALID_TRANSFORM       - Unused.
   * @property {number}  INVALID_PROTOCOL        - The protocol (or version) is not supported.
   * @property {number}  UNSUPPORTED_CLIENT_TYPE - Unused.
   */
  interface TApplicationExceptionType {
    'UNKNOWN': number;
    'UNKNOWN_METHOD': number;
    'INVALID_MESSAGE_TYPE': number;
    'WRONG_METHOD_NAME': number;
    'BAD_SEQUENCE_ID': number;
    'MISSING_RESULT': number;
    'INTERNAL_ERROR': number;
    'PROTOCOL_ERROR': number;
    'INVALID_TRANSFORM': number;
    'INVALID_PROTOCOL': number;
    'UNSUPPORTED_CLIENT_TYPE': number;
  }
  var TApplicationExceptionType: TApplicationExceptionType;

  /**
   * TApplicationException is the exception class used to propagate exceptions from an RPC server back to a calling client.
   */
  class TApplicationException extends TException {
    code: number;

    /**
     * Initializes a Thrift TApplicationException instance.
     * @param {string} message - The TApplicationException message (distinct from the Error message).
     * @param {Thrift.TApplicationExceptionType} [code] - The TApplicationExceptionType code.
     */
    constructor(message: string, code?: number);

    /**
     * Read a TApplicationException from the supplied protocol.
     * @param {object} input - The input protocol to read from.
     */
    read(input: any): void;

    /**
     * Write a TApplicationException to the supplied protocol.
     * @param {object} output - The output protocol to write to.
     */
    write(output: any): void;

    /**
     * Returns the application exception code set on the exception.
     * @returns {Thrift.TApplicationExceptionType} exception code
     */
    getCode(): number;
  }

  /**
   * The Apache Thrift Transport layer performs byte level I/O between RPC
   * clients and servers. The JavaScript Transport object type uses Http[s]/XHR and is
   * the sole browser based Thrift transport. Target servers must implement the http[s] 
   * transport (see: node.js example server).
   */
  class TXHRTransport {
    url: string;
    wpos: number;
    rpos: number;
    useCORS: any;
    send_buf: string;
    recv_buf: string;

    /**
     * If you do not specify a url then you must handle XHR operations on
     * your own. This type can also be constructed using the Transport alias
     * for backward compatibility.
     * @param {string} [url] - The URL to connect to.
     * @param {any} [options] - Options.
     */
    constructor(url?: string, options?: any);

    /**
     * Gets the browser specific XmlHttpRequest Object.
     * @returns {object} the browser XHR interface object
     */
    getXmlHttpRequestObject(): any;

    /**
     * Sends the current XRH request if the transport was created with a URL and
     * the async parameter if false. If the transport was not created with a URL
     * or the async parameter is True or the URL is an empty string, the current 
     * send buffer is returned.
     * @param {object} async - If true the current send buffer is returned.
     * @param {object} callback - Optional async completion callback.
     * @returns {undefined|string} Nothing or the current send buffer.
     */
    flush(async: any, callback?: Function): string;

    /**
     * Creates a jQuery XHR object to be used for a Thrift server call.
     * @param {object} client - The Thrift Service client object generated by the IDL compiler.
     * @param {object} postData - The message to send to the server.
     * @param {function} args - The function to call if the request suceeds.
     * @param {function} recv_method - The Thrift Service Client receive method for the call.
     * @returns {object} A new jQuery XHR object.
     */
    jqRequest(client: any, postData: any, args: Function, recv_method: Function): any;

    /**
     * Sets the buffer to use when receiving server responses.
     * @param {string} buf - The buffer to receive server responses.
     */
    setRecvBuffer(buf: string): void;

    /**
     * Returns true if the transport is open, in browser based JavaScript
     * this function always returns true.
     * @returns {boolean} Always True.
     */
    isOpen(): boolean;

    /**
     * Opens the transport connection, in browser based JavaScript
     * this function is a nop.
     */
    open(): void;

    /**
     * Closes the transport connection, in browser based JavaScript
     * this function is a nop.
     */
    close(): void;

    /**
     * Returns the specified number of characters from the response
     * buffer.
     * @param {number} len - The number of characters to return.
     * @returns {string} Characters sent by the server.
     */
    read(len: number): string;

    /**
     * Returns the entire response buffer.
     * @returns {string} Characters sent by the server.
     */
    readAll(): string;

    /**
     * Sets the send buffer to buf.
     * @param {string} buf - The buffer to send.
     */
    write(buf: string): void;

    /**
     * Returns the send buffer.
     * @returns {string} The send buffer.
     */
    getSendBuffer(): string;
  }

  /**
   * Old alias of the TXHRTransport for backwards compatibility.
   */
  class Transport extends TXHRTransport { }

  /**
   * The Apache Thrift Transport layer performs byte level I/O 
   * between RPC clients and servers. The JavaScript TWebSocketTransport object 
   * uses the WebSocket protocol. Target servers must implement WebSocket.
   */
  class TWebSocketTransport {
    url: string;           //Where to connect
    socket: any;           //The web socket
    callbacks: any[];      //Pending callbacks
    send_pending: any[];   //Buffers/Callback pairs waiting to be sent
    send_buf: string;      //Outbound data, immutable until sent
    recv_buf: string;      //Inbound data
    rb_wpos: number;       //Network write position in receive buffer
    rb_rpos: number;       //Client read position in receive buffer

    /**
     * Constructor Function for the WebSocket transport.
     * @param {string } [url] - The URL to connect to.
     */
    constructor(url: string);

    __reset(url): void;

    /**
     * Sends the current WS request and registers callback. The async 
     * parameter is ignored (WS flush is always async) and the callback 
     * function parameter is required.
     * @param {object} async - Ignored.
     * @param {object} callback - The client completion callback.
     * @returns {undefined|string} Nothing (undefined) 
     */
    flush(async: any, callback: any): string;

    __onOpen(): void;

    __onClose(): void;

    __onMessage(): void;

    __onError(): void;

    /**
     * Sets the buffer to use when receiving server responses.
     * @param {string} buf - The buffer to receive server responses.
     */
    setRecvBuffer(buf: string): void;

    /**
     * Returns true if the transport is open
     * @returns {boolean} 
     */
    isOpen(): boolean;

    /**
     * Opens the transport connection
     */
    open(): void;

    /**
     * Closes the transport connection
     */
    close(): void;

    /**
     * Returns the specified number of characters from the response
     * buffer.
     * @param {number} len - The number of characters to return.
     * @returns {string} Characters sent by the server.
     */
    read(len: number): string;

    /**
     * Returns the entire response buffer.
     * @returns {string} Characters sent by the server.
     */
    readAll(): string;

    /**
     * Sets the send buffer to buf.
     * @param {string} buf - The buffer to send.
     */
    write(buf: string): void;

    /**
     * Returns the send buffer.
     * @returns {string} The send buffer.
     */
    getSendBuffer(): string;
  }

  /**
   * Apache Thrift Protocols perform serialization which enables cross 
   * language RPC. The Protocol type is the JavaScript browser implementation 
   * of the Apache Thrift TJSONProtocol.
   */
  class TJSONProtocol {
    transport: Transport;

    /**
     * Thrift IDL type Id to string mapping.
     * The mapping table looks as follows:
     * Thrift.Type.BOOL   -> "tf": True/False integer.
     * Thrift.Type.BYTE   -> "i8": Signed 8 bit integer.
     * Thrift.Type.I16    -> "i16": Signed 16 bit integer.
     * Thrift.Type.I32    -> "i32": Signed 32 bit integer.
     * Thrift.Type.I64    -> "i64": Signed 64 bit integer.
     * Thrift.Type.DOUBLE -> "dbl": 64 bit IEEE 854 floating point.
     * Thrift.Type.STRUCT -> "rec": A multifield type.
     * Thrift.Type.STRING -> "str": Array of bytes representing a string of characters.
     * Thrift.Type.MAP    -> "map": A collection type (map/associative-array/dictionary).
     * Thrift.Type.LIST   -> "lst": A collection type (unordered).
     * Thrift.Type.SET    -> "set": A collection type (unordered and without repeated values).
     */
    Type: { [k: number]: string };

    /**
     * Thrift IDL type string to Id mapping.
     * The mapping table looks as follows:
     * "tf"  -> Thrift.Type.BOOL  
     * "i8"  -> Thrift.Type.BYTE  
     * "i16" -> Thrift.Type.I16   
     * "i32" -> Thrift.Type.I32   
     * "i64" -> Thrift.Type.I64   
     * "dbl" -> Thrift.Type.DOUBLE
     * "rec" -> Thrift.Type.STRUCT
     * "str" -> Thrift.Type.STRING
     * "map" -> Thrift.Type.MAP   
     * "lst" -> Thrift.Type.LIST  
     * "set" -> Thrift.Type.SET   
     */
    RType: { [k: string]: number };

    /**
     * The TJSONProtocol version number.
     */
    Version: number;

    /**
     * Initializes a Thrift JSON protocol instance.
     * @param {Thrift.Transport} transport - The transport to serialize to/from.
     */
    constructor(transport: Transport);

    /**
     * Returns the underlying transport.
     * @returns {Thrift.Transport} The underlying transport.
     */
    getTransport(): Transport;

    /**
     * Serializes the beginning of a Thrift RPC message.
     * @param {string} name - The service method to call.
     * @param {Thrift.MessageType} messageType - The type of method call.
     * @param {number} seqid - The sequence number of this call (always 0 in Apache Thrift).
     */
    writeMessageBegin(name: string, messageType: number, seqid: number): void;

    /**
     * Serializes the end of a Thrift RPC message.
     */
    writeMessageEnd(): void;

    /**
     * Serializes the beginning of a struct.
     * @param {string} name - The name of the struct.
     */
    writeStructBegin(name?: string): void;

    /**
     * Serializes the end of a struct.
     */
    writeStructEnd(): void;

    /**
     * Serializes the beginning of a struct field.
     * @param {string} name - The name of the field.
     * @param {Thrift.Protocol.Type} fieldType - The data type of the field.
     * @param {number} fieldId - The field's unique identifier.
     */
    writeFieldBegin(name: string, fieldType: string[], fieldId: number): void;

    /**
     * Serializes the end of a field.
     */
    writeFieldEnd(): void;

    /**
     * Serializes the end of the set of fields for a struct.
     */
    writeFieldStop(): void;

    /**
     * Serializes the beginning of a map collection.
     * @param {Thrift.Type} keyType - The data type of the key.
     * @param {Thrift.Type} valType - The data type of the value.
     * @param {number} [size] - The number of elements in the map (ignored).
     */
    writeMapBegin(keyType: number, valType: number, size?: number): void;

    /**
     * Serializes the end of a map.
     */
    writeMapEnd(): void;

    /**
     * Serializes the beginning of a list collection.
     * @param {Thrift.Type} elemType - The data type of the elements.
     * @param {number} size - The number of elements in the list.
     */
    writeListBegin(elemType: number, size: number): void;

    /**
     * Serializes the end of a list.
     */
    writeListEnd(): void;

    /**
     * Serializes the beginning of a set collection.
     * @param {Thrift.Type} elemType - The data type of the elements.
     * @param {number} size - The number of elements in the list.
     */
    writeSetBegin(elemType: number, size: number): void;

    /**
     * Serializes the end of a set.
     */
    writeSetEnd(): void;

    /** Serializes a boolean */
    writeBool(value: boolean): void;

    /** Serializes a number */
    writeByte(i8: number): void;

    /** Serializes a number */
    writeI16(i16: number): void;

    /** Serializes a number */
    writeI32(i32: number): void;

    /** Serializes a number */
    writeI64(i64: number): void;

    /** Serializes a number */
    writeDouble(dbl: number): void;

    /** Serializes a string */
    writeString(str: string): void;

    /** Serializes a string */
    writeBinary(str: string): void;

    /**
       @class
       @name AnonReadMessageBeginReturn
       @property {string} fname - The name of the service method.
       @property {Thrift.MessageType} mtype - The type of message call.
       @property {number} rseqid - The sequence number of the message (0 in Thrift RPC).
     */
    /** 
     * Deserializes the beginning of a message. 
     * @returns {AnonReadMessageBeginReturn}
     */
    readMessageBegin(): { fname: string; mtype: number; rseqid: number };

    /** Deserializes the end of a message. */
    readMessageEnd(): void;

    /** 
     * Deserializes the beginning of a struct. 
     * @param {string} [name] - The name of the struct (ignored).
     * @returns {object} - An object with an empty string fname property.
     */
    readStructBegin(name?: string): any;

    /** Deserializes the end of a struct. */
    readStructEnd(): void;

    /**
       @class
       @name AnonReadFieldBeginReturn
       @property {string} fname - The name of the field (always '').
       @property {Thrift.Type} ftype - The data type of the field.
       @property {number} fid - The unique identifier of the field.
     */
    /** 
     * Deserializes the beginning of a field. 
     * @returns {AnonReadFieldBeginReturn}
     */
    readFieldBegin(): { fname: string; ftype: number; fid: number };

    /** Deserializes the end of a field. */
    readFieldEnd(): void;

    /**
       @class
       @name AnonReadMapBeginReturn
       @property {Thrift.Type} ktype - The data type of the key.
       @property {Thrift.Type} vtype - The data type of the value.
       @property {number} size - The number of elements in the map.
     */
    /** 
     * Deserializes the beginning of a map. 
     * @returns {AnonReadMapBeginReturn}
     */
    readMapBegin(): { ktype: number; vtype: number; size: number };

    /** Deserializes the end of a map. */
    readMapEnd(): void;

    /**
       @class
       @name AnonReadColBeginReturn
       @property {Thrift.Type} etype - The data type of the element.
       @property {number} size - The number of elements in the collection.
     */
    /** 
     * Deserializes the beginning of a list. 
     * @returns {AnonReadColBeginReturn}
     */
    readListBegin(): { etype: number; size: number };

    /** Deserializes the end of a list. */
    readListEnd(): void;

    /** 
     * Deserializes the beginning of a set. 
     * @param {Thrift.Type} elemType - The data type of the elements (ignored).
     * @param {number} size - The number of elements in the list (ignored).
     * @returns {AnonReadColBeginReturn}
     */
    readSetBegin(elemType?: number, size?: number): { etype: number; size: number };

    /** Deserializes the end of a set. */
    readSetEnd(): void;

    /** Returns an object with a value property set to 
     *  False unless the next number in the protocol buffer 
     *  is 1, in which case the value property is True. */
    readBool(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readByte(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readI16(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readI32(f?: any): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readI64(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readDouble(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readString(): Object;

    /** Returns an object with a value property set to the 
        next value found in the protocol buffer. */
    readBinary(): Object;

    /** 
     * Method to arbitrarily skip over data (not implemented).
     */
    skip(type: any): void;
  }

  /**
   * Old alias of the TXHRTransport for backwards compatibility.
   */
  class Protocol extends TJSONProtocol { }

  class MultiplexProtocol extends Protocol {
    serviceName: string;

    /**
     * Initializes a MutilplexProtocol Implementation as a Wrapper for Thrift.Protocol.
     * @param {string} srvName
     * @param {Thrift.Transport} trans
     * @param {any} [strictRead]
     * @param {any} [strictWrite]
     */
    constructor(srvName: string, trans: Transport, strictRead?: any, strictWrite?: any);
  }

  class Multiplexer {
    seqid: number;

    /** Instantiates a multiplexed client for a specific service.
     * @param {String} serviceName - The transport to serialize to/from.
     * @param {Thrift.ServiceClient} SCl - The Service Client Class.
     * @param {Thrift.Transport} transport - Thrift.Transport instance which provides remote host:port.
    */
    createClient(serviceName: string, SCl: any, transport: Transport);
  }
}