/*
 * 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 succeeds.
     * @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);
  }
}