#ifndef EPP_IDL
#define EPP_IDL

/*
** EPP-RTK IDL
**
** Authors: 
**      Daniel Manley (Tucows Inc)
**      Asbjorn Steira Mikkelsen (The Global Name Registry, Limited)
**      Frank Thompson (Tucows Inc)
**
** $Header: /cvsroot/epp-rtk/epp-rtk/idl/epprtk/epp.idl,v 1.1 2004/12/07 15:22:52 ewang2004 Exp $
** $Revision: 1.1 $
** $Date: 2004/12/07 15:22:52 $
*/

module epp
{

    //
    // enumerations
    //
    enum epp_TransferOpType
    { 
        APPROVE,
        CANCEL,
        QUERY,
        REJECT,
        REQUEST
    };

    //
    // Types used in object transfers.
    //
    enum epp_TransferStatusType
    { 
        CLIENT_APPROVED,
        CLIENT_CANCELLED,
        CLIENT_REJECTED,
        PENDING,
        SERVER_APPROVED,
        SERVER_CANCELLED
    };

    //
    // Types used in object polls.
    //
    enum epp_PollOpType
    { 
        ACK,
        REQ
    };

    //
    // Types used in auth ID.
    //
    enum epp_AuthInfoType
    { 
        PW,
        EXT
    };

    //
    // Types used in Data Collection Policity Specifications
    //
    enum epp_dcpAccessType
    {
        ALL,
        NONE_ACCESS,
        NULL_ACCESS,
        OTHER,
        PERSONAL,
        PERSONAL_AND_OTHER
    };
    enum epp_dcpPurposeType
    {
        ADMIN,
        CONTACT,
        // have to qualify "other" here because it conflicted with
        // "other" from epp_dcpRecipientType
        OTHER_PURPOSE,
        PROV
    };
    enum epp_dcpRecipientType
    {
        // have to qualify "other" here because it conflicted with
        // "other" from epp_dcpPurposeType
        OTHER_RECIPIENT,
        // OURS requires additional m_ours_type to be set
        OURS,
        // could not use the spelling "public" because
        // it's reserved word.
        PUBLIK,
        SAME,
        UNRELATED
    };
    enum epp_dcpRetentionType
    {
        BUSINESS,
        INDEFINITE,
        LEGAL,
        NONE,
        STATED
    };

    enum epp_dcpExpiryType
    {
        ABSOLUTE,
        RELATIVE
    };
    
    // Sequences for the DCP types
    typedef sequence<epp_dcpPurposeType> epp_dcpPurpose_seq;

    //
    // common base types
    //
    typedef string epp_string;
    typedef string epp_xml_string;
    typedef sequence<epp_string> epp_string_seq;
    typedef sequence<epp_xml_string> epp_xml_string_seq;
    typedef short epp_short;
    typedef long epp_long;
    typedef boolean epp_boolean;
    typedef any epp_any;
    typedef string epp_date;
    typedef string epp_datetime;
    typedef epp_string epp_trid;

    /*
     * Repository Object IDentifiers are formed as follows:
     * [1-80 characters] "-" [1-8 characters]
     * The first 1-80 characters are assigned by and must be unique within
     * the repository.
     * The last 1-8 characters are assigned by and must be unique within
     * a centralized management facility, such as an IANA registry.
     */
    typedef epp_string epp_roid;
    typedef sequence<epp_roid> epp_roid_seq;

    //
    // common data structures
    //
    struct epp_TransID
    {
        epp_trid m_client_trid;
        epp_trid m_server_trid;
    };

    struct epp_AuthInfo
    {
        // AuthInfo is a choice between two types: PW and EXT.
        // Either must have a value.  And roid attribute is used
        // if the auth info is for another object (on behalf of).
        epp_AuthInfoType m_type;
        epp_roid m_roid;
        epp_string m_value;
    };

    struct epp_ResultValue
    {
        // Can be null/empty if the XML is not parsable.
        epp_string m_namespace;
        // The xml string provided within the <value> element
        // This should simply be the contents of the <value>
        // element if the XML is unparsable.
        epp_xml_string m_xml_string;
        // The offending element's tag name
        // Can be null/empty if the XML is not parsable.
        epp_string m_element_name;
        // The actual value of the offending tag.
        // This should simply be the contents of the <value>
        // element if the XML is unparsable.
        epp_string m_element_value;
    };
    
    struct epp_ExtResultValue
    {
        epp_ResultValue m_value;
        epp_string m_reason;
    };
    
    typedef sequence<epp_ResultValue> epp_resultvalue_seq;
    typedef sequence<epp_ExtResultValue> epp_extresultvalue_seq;
    
    struct epp_Result
    {
        epp_short m_code;
        epp_resultvalue_seq m_values;
        epp_extresultvalue_seq m_ext_values;
        // Maybe these three should be part of
        // an epp_Msg or something
        epp_string m_msg;
        epp_string m_lang;
    };

    typedef sequence<epp_Result> epp_result_seq;

    //
    // common exceptions
    //
    exception epp_Exception
    {
        epp_result_seq m_details;
        epp_TransID m_trans_id;
        // Multiple extensions allows in EPP
        epp_xml_string_seq m_ext_strings;
    };

    exception epp_XMLException
    {
        epp_string m_error_message;
    };

    // For registry-required extension data,
    // the owness will be on the registry to provide code to convert
    // whatever data structs/types/classes to XML strings.  The RTK
    // will take care of including the extension XML string in to the EPP 
    // message.
    interface epp_Extension
    {
        epp_string toXML() raises (epp_XMLException);
        void fromXML(in epp_string xml) raises (epp_XMLException);
    };
    typedef sequence<epp_Extension> epp_extension_seq;
    
    struct epp_Command
    {
        epp_extension_seq m_extensions;
        epp_trid m_client_trid;
    };

    struct epp_TransferRequest
    {
        epp_AuthInfo m_auth_info;
        epp_TransferOpType m_op;
    };

    struct epp_ExtMessage
    {
        epp_string m_lang;
        epp_string m_value;
    };
    
    struct epp_MessageQueue
    {
        epp_long m_count;
        epp_datetime m_queue_date;
        // This can contain some XML but it is not parsable or
        // predictable as per the EPP spec.
        epp_ExtMessage m_msg;
        // XXX should this be an epp_long?
        epp_string m_id;
    };

    struct epp_Response
    {
        epp_result_seq m_results;
        epp_MessageQueue m_message_queue;
        // Because of the difficulty in having the RTK
        // instantiate the right epp_Extension, these 
        // extensions will be an XML String.  The 
        // registrar will have to separately call 
        // fromXML() on the individual strings with the
        // appropriate object they are expecting back from 
        // the registry.
        epp_xml_string_seq m_extension_strings;
        epp_TransID m_trans_id;
    };

    struct epp_CheckResult
    {
        // The object's identifier (domain name, contact id, etc...)
        epp_string m_value;
        // Boolean flag to say whether the object can be
        // provisioned by the registry.
        epp_boolean m_avail;
        // Optional reason for the object not being available
        // Max length 32 by the XSD specifications
        epp_string m_reason;
        // The language for the reason, default "en"
        epp_string m_lang;
    };

    typedef sequence<epp_CheckResult> epp_check_result_seq;

    //
    // Interface for objects that can take request and response
    // data and go to and from XML, respectively.
    //
    interface epp_Action
    {
        epp_string toXML() raises (epp_Exception, epp_XMLException);
        void fromXML(in epp_string xml) raises (epp_Exception, epp_XMLException);
    };
    
    /////////////
    //  hello  //
    /////////////

    typedef epp_string_seq epp_objuri_seq;
    typedef epp_string_seq epp_exturi_seq;

    struct epp_ServiceMenu
    {
        epp_string_seq m_versions;
        epp_string_seq m_langs;
        epp_objuri_seq m_services;
        epp_exturi_seq m_extensions;
    };
    
    struct epp_dcpRecipient
    {
        epp_dcpRecipientType m_type;
        // m_rec_desc is only required if m_type
        // is OURS
        epp_string m_rec_desc;
    };
    typedef sequence<epp_dcpRecipient> epp_dcpRecipient_seq;

    struct epp_dcpStatement
    {
        epp_dcpPurpose_seq m_purposes;
        epp_dcpRecipient_seq m_recipients;
        epp_dcpRetentionType m_retention;
    };
    
    typedef sequence<epp_dcpStatement> epp_dcpStatement_seq;
    
    struct epp_dcpExpiry
    {
        epp_dcpExpiryType m_type;
        epp_string m_value;
    };
    
    struct epp_DataCollectionPolicy
    {
        epp_dcpAccessType m_access;
        epp_dcpStatement_seq m_statements;
        epp_dcpExpiry m_expiry;
    };
    
    struct epp_Greeting
    {
        epp_string m_server_id;
        epp_datetime m_server_date;
        epp_ServiceMenu m_svc_menu;
        epp_DataCollectionPolicy m_dcp;
    };

    interface epp_Hello : epp_Action
    {
        epp_Greeting getResponseData();
    };
        
    /////////////
    //  login  //
    /////////////
    struct epp_Options
    {
        epp_string m_version;
        epp_string m_lang;
    };

    struct epp_LoginReq
    {
        epp_Command m_cmd;
        epp_string m_client_id;
        epp_string m_password;
        epp_string m_new_password;
        epp_Options m_options;
        epp_objuri_seq m_services;
        epp_exturi_seq m_extensions;
    };

    struct epp_LoginRsp
    {
        epp_Response m_rsp;
    };

    interface epp_Login : epp_Action
    {
        void setRequestData(in epp_LoginReq data);
        epp_LoginRsp getResponseData();
    };
        
    //////////////
    //  logout  //
    //////////////
    struct epp_LogoutReq
    {
        epp_extension_seq m_extensions;
        epp_trid m_client_trid;
    };

    struct epp_LogoutRsp
    {
        epp_Response m_rsp;
    };

    interface epp_Logout : epp_Action
    {
        void setRequestData(in epp_LogoutReq data);
        epp_LogoutRsp getResponseData();
    };

    ////////////
    //  poll  //
    ////////////
    struct epp_PollReq
    {
        epp_Command m_cmd;
        epp_PollOpType m_op;
        epp_string m_msgID;
    };

    interface epp_PollResData
    {
        // each subinterface of this interface
        // must return a string representing its
        // type.  This string will be a const in
        // the subinterface.
        epp_string getType();
    };

    struct epp_PollRsp
    {
        epp_Response m_rsp;
        epp_PollResData m_res_data;
    };

    interface epp_Poll : epp_Action
    {
        void setRequestData(in epp_PollReq parms);
        epp_PollRsp getResponseData();
    };
        
    ///////////////
    //  session  //
    ///////////////
    interface epp_Session
    {
        // take an object implementing the epp_Action interface, get its
        // XML, send it to the server, take the response XML, pass it to
        // to the same epp_Action and return the epp_Action (which might
        // require some casting on the RTK user's part).
        epp_Action processAction(in epp_Action request) raises (epp_Exception, epp_XMLException);
        // Alternative to processAction().  Possibly aids in avoiding casting
        // which might be required by processAction().
        epp_string processXML(in epp_string request_xml) raises (epp_Exception, epp_XMLException);

        const epp_short EPP_COMMAND_COMPLETED_SUCCESSFULLY = 1000;
        const epp_short EPP_COMMAND_COMPLETED_SUCCESSFULLY_ACTION_PENDING = 1001;

        const epp_short EPP_COMMAND_COMPLETED_SUCCESSFULLY_NO_MESSAGES = 1300;
        const epp_short EPP_COMMAND_COMPLETED_SUCCESSFULLY_ACK_TO_DEQUEUE = 1301;
        
        const epp_short EPP_COMMAND_COMPLETED_SUCCESSFULLY_ENDING_SESSION = 1500;

        const epp_short EPP_UNKNOWN_COMMAND = 2000;
        const epp_short EPP_COMMAND_SYNTAX_ERROR = 2001;
        const epp_short EPP_COMMAND_USE_ERROR = 2002;
        const epp_short EPP_REQUIRED_PARAMETER_MISSING = 2003;
        const epp_short EPP_PARAMETER_VALUE_RANGE_ERROR = 2004;
        const epp_short EPP_PARAMETER_VALUE_SYNTAX_ERROR = 2005;

        const epp_short EPP_UNIMPLEMENTED_PROTOCOL_VERSION = 2100;
        const epp_short EPP_UNIMPLEMENTED_COMMAND = 2101;
        const epp_short EPP_UNIMPLEMENTED_OPTION = 2102;
        const epp_short EPP_UNIMPLEMENTED_EXTENSION = 2103;
        const epp_short EPP_BILLING_FAILURE = 2104;
        const epp_short EPP_OBJECT_IS_NOT_ELIGIBLE_FOR_RENEWAL = 2105;
        const epp_short EPP_OBJECT_IS_NOT_ELIGIBLE_FOR_TRANSFER = 2106;

        const epp_short EPP_AUTHENTICATION_FAILURE = 2200;
        const epp_short EPP_AUTHORIZATION_FAILURE = 2201;
        const epp_short EPP_INVALID_AUTHORIZATION_IDENTIFIER = 2202;

        const epp_short EPP_OBJECT_PENDING_TRANSFER = 2300;
        const epp_short EPP_OBJECT_NOT_PENDING_TRANSFER = 2301;
        const epp_short EPP_OBJECT_EXISTS = 2302;
        const epp_short EPP_OBJECT_DOES_NOT_EXIST = 2303;
        const epp_short EPP_OBJECT_STATUS_PROHIBITS_OPERATION = 2304;
        const epp_short EPP_OBJECT_ASSOCIATION_PROHIBITS_OPERATION = 2305;
        const epp_short EPP_PARAMETER_VALUE_POLICY_ERROR = 2306;
        const epp_short EPP_UNIMPLEMENTED_OBJECT_SERVICE = 2307;
        const epp_short EPP_DATA_MANAGEMENT_POLICY_VIOLATION = 2308;

        const epp_short EPP_COMMAND_FAILED = 2400;

        const epp_short EPP_COMMAND_FAILED_SERVER_CLOSING_CONNECTION = 2500;
        const epp_short EPP_AUTHENTICATION_ERROR_SERVER_CLOSING_CONNECTION = 2501;
        const epp_short EPP_SESSION_LIMIT_EXCEEDED_SERVER_CLOSING_CONNECTION = 2502;

        //
        // Custom errors for the RTK
        //
        const epp_short RTK_COMMUNICATIONS_FAILURE = 2600;
        const epp_short RTK_UNEXPECTED_SERVER_DISCONNECT = 2601;
        
    };
};

#endif
