// Copyright 2020 Siemens Digital Industries Software
// ==================================================
// Copyright 2017.
// Siemens Product Lifecycle Management Software Inc.
// All Rights Reserved.
// ==================================================
// Copyright 2020 Siemens Digital Industries Software

/**
    @file

    Contains common structures and functions for Lifecycle Interoperability Services Framework.

*/

#ifndef LIS0LISFMWRK_LISFMWRKUTILS_HXX
#define LIS0LISFMWRK_LISFMWRKUTILS_HXX

#include <string>
#include <vector>

#include <unidefs.h>

#include <base_utils/TcBaseTypes.hxx>
#include <Lis0lisfmwrk/Lis0ServiceDef.hxx>
#include <Lis0lisfmwrk/libLis0lisfmwrk_exports.h>


/**
    @defgroup LIS0LISFMWRK Lifecycle Interoperability Services Framework
    @ingroup TC
    
    This file contains the definition of common structures and function.

    @{
*/

namespace lis0lisfmwrk
{
    class LisfmwrkUtils;
}

/**
    Defines different values that can be used as Request Method
*/
enum RequestMethod
{
    GET,    /**< Request Method GET */
    POST,   /**< Request Method POST */
    PUT     /**< Request Method PUT */
};  
/**
   Defines different values that can be used as Response Format
*/
enum ResponseFormat
{
    XML,                       /**< Response Format XML */
    RDF_XML,                   /**< Response Format RDF+XML */
    OSLC_COMPACT_XML,          /**< Response Format OSLC Compact XML */
    JSON                       /**< Response Format Json */
};

/**
   User Authentication Tokens Information
*/
typedef struct UserOAuthTokens
{
    std::string lis0AccessToken;            /**< User Access Token for authentication */
    std::string lis0AccessTokenSecret;      /**< User Access Secret Token for authenticaiton */
    std::string lis0RequestToken;           /**< User Request Token for authentication */
    std::string lis0RequestTokenSecret;     /**< User Request Secret Token for authentication */
} UserTokens;

/**
   Http request input
*/

typedef struct HttpRequestInput
{
    std::string url;                               /**< URL to be requested */
    RequestMethod method;                          /**< Http Request Method */
    std::string postData;                          /**< Request Body for Post Data */
    bool isAuthRequired;                           /**< Checks user authentication is required or not */
    std::string consumerKey;                       /**< ConsumerKey for authentication */
    std::string consumerSecret;                    /**< Consumer Secret key for authentication */
    std::string tokenKey;                          /**< Token Key for authentication */
    std::string tokenSecret;                       /**< Token Secret key for authentication */
    std::string cookieStr;                         /**< Domain of Service Provider */
    std::map<std::string, std::string> headers;    /**< Request Header for Http Request */

} HttpRequestInputS;

/**
   Service provider information
*/
typedef struct ServiceProviderInfo
{
    std::string providerUrl;            /**< URL of service provider */
    std::string providerName;           /**< Name of service provider */
    std::string description;            /**< Description of service provider */
    std::vector<std::string> domain;    /**< Domain of Service Provider */

} ServiceProviderInfoS;

/**
    Service Provider Catalog Information
*/

typedef struct ServiceProviderCatalogInfoExtend : ServiceProviderCatalogInfo
{
    std::vector <std::string> catalogDomain;     /**< Domain of Service Provider Catalog */

} LIS_service_catalog_info_extend_t;

/**
 * Root Services response information
*/

typedef struct RootServiceResponseExtend : RootServiceResponseInfo
{
    std::vector<LIS_service_catalog_info_t> catalogList;    /**< Array of catalogs */
    LIS_Oauth_info_s oauthInfo;                             /**< OAuth information */
} LIS_rootservice_response_extend_t;

/**
 * Delegated Dialog information
*/
typedef struct LIS_delegated_dialog_info_extend_s:LIS_delegated_dialog_info_s
{
    std::string domain;                 /**< Domain of Delegated Dialog */
} LIS_delegated_dialog_info_extend_t;

/**
 * Factory Service information
*/
typedef struct LIS_factory_service_info_extend_s:LIS_factory_service_info_s
{
    std::string domain;          /**< Domain for Factory Service */
} LIS_factory_service_info_extend_t;

/**
 * Service response information
*/
typedef struct ServiceResponseInfoExtend 
{
    std::vector<LIS_delegated_dialog_info_extend_t> dialogList;             /**< Array of creation dialogs */
    std::vector<LIS_factory_service_info_extend_t> factoryServiceList;      /**< Array of factory service */
} LIS_service_info_extend_t;


class LIS0LISFMWRK_API lis0lisfmwrk::LisfmwrkUtils
{
    public:
    /**
        Creates request input information from a given HTTP URL.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>LIS0LISFMWRK_url_use_wrongformat if @p url provided URL is not properly formatted.
            <li>#LIS0LISFMWRK_input_request_body_empty if the request body in @p postData is invalid.
            <li>#CXPOM_invalid_tag if  @p userAuthentication is not a valid User.
        </ul>
     */
    static int createHttpRequestInput( const std::string &url,               /**< (I) The HTTP URL */
                                       const RequestMethod method,           /**< (I) The request method type */
                                       const std::string &postData,          /**< (I) The request body of POST request */
                                       const tag_t userAuthentication,       /**< (I) The User Authentication */
                                       const ResponseFormat &format,         /**< (I) The response format for a given URL */
                                       HttpRequestInputS *requestInput       /**< (O) The output request by a given HTTP URL */
                                       );
    /**
        Retrieves the response and timestamp of authorization by a given HTTP connection URL.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_url_not_authorized if @p isRequestTokenUrl url cannot be accessed because of authorization issues.
            <li>#LIS0LISFMWRK_url_cannot_resolve_host if the host cannot be extracted from @p isRequestTokenUrl.
            <br/>Please check that the provided URL is correct
            <li>#LIS0LISFMWRK_url_use_wrongformat if @p isRequestTokenUrl is not properly formatted.
            <li>#LIS0LISFMWRK_input_request_body_empty if the request body in @p requestInput is invalid.
        </ul>
     */
    static int requestHttps( const bool isRequestTokenUrl,                 /**< (I) Specifies if this HTTP Request is authorizised.*/
                             const HttpRequestInputS &requestInput,        /**< (I) The input HTTP URL*/
                             std::string& responseString,                  /**< (O) The response of requested HTPP URL */
                             long &responseCode,                           /**< (O) Status of request URL */
                             std::string& eTagString,                      /**< (O) TimeStamp of authorization */
                             int getResponseHeader=0                       /**< (I) Response header with etag */
                             );
    /**
        Retrieves the response from a given HTTP Request Input .
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_input_request_body_empty if the request body in @p requestInput is invalid.
        </ul>
    */
    static int requestHttps( const HttpRequestInputS &requestInput,     /**< (I) The HTTP request. */
                             std::string& responseString                /**< (O) The response of HTTP request. */
                             );
    /**
        Requests an https connection and outputs the response code along with with its timestamp.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_input_request_body_empty if the request body in @p requestInput is invalid.
        </ul>
     */
    static int requestHttps( const HttpRequestInputS &requestInput,     /**< (I) The HTTP Request */
                             std::string& responseString,               /**< (O) The response of requested HTTP */
                             long &responseCode,                        /**< (O) The response Code of Requested HTTP */
                             std::string& eTagString,                   /**< (O) TimeStamp of request */
                             int getResponseHeader=0                    /**< (I) The response header with etag */
                             );
    /**
        Retrieves the list of service provider catalog and authentication information from a given response content.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseContent is invalid HTTP response. 
            <br/>Probably it is not a good OSLC ( Open Services for Lifecycle Collabration ) provider.
        </ul>
     */
    static int parseRootServiceContent( const std::string& responseContent,                     /**< (I) The response content of root services */
                                        LIS_rootservice_response_extend_t &responseInfo         /**< (O) The list of service provider catalogs and authentication information */
                                        );
    /**
        Parses and retrieves the information of catalog services from  a given response content.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseContent is invalid HTTP response. 
            <br/>Probably it is not a good OSLC provider.
        </ul>
     */
    static int parseCatalogContent( const std::string& responseContent,                     /**< (I) The response content of catalog services */
                                    std::vector<ServiceProviderInfo> &providerInfoList      /**< (O) The information of catalog services */
                                    );
    /**
        Parses and retrieves the list of dialogs of services from a given response content.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseContent is invalid HTTP response.
            <br/>Probably it is not a good OSLC provider.
        </ul>
     */
    static int parseServiceContent( const std::string& responseContent,         /**< (I) The response content of services */
                                    LIS_service_info_extend_t &serviceInfo      /**< (O) The list of dialogs of a given services */
                                    );
    /**
        Parse and Retrives the information of Resource by a given Response Content.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseContent is invalid HTTP response.
            <br/>Probably it is not a good OSLC provider.
        </ul>
     */
    static int parseResourceContent( const std::string& responseContent,    /**< (I) The response content of ResourceShape. */
                                     LIS_resource_info_t &resourceInfo      /**< (O) The information of resource. */
                                     );
    /**
        Validates the License Feature Package
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_validate_license_failed if @p licensePackage is not available.
            <br/>Please contact the system administrator.
        </ul>
     */
    static int validateLicense( const char* licensePackage    /**< (I) The License Feature Package */
                                );
    /**
        Retrieves the User Authorization URL from a given Service Provider.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p serviceProvider is invalid type.
        </ul>
     */
    static int getOAuthAuthorizationURL( const tag_t serviceProvider,   /**< (I) The service provider tag */
                                         char** userAuthorizationUrl    /**< (O) The user authorization URL */
                                         );
    /**
        Retrieves the list of Relations from a given Context Object and Remote Object. -- add one more
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p uidContextObject is invalid UID.
            <li>#CXPOM_invalid_tag if @p remoteObjectType is invalid type.
            <li>#CXPOM_invalid_tag if @p uidServiceProvider is invalid UID.
        </ul>
    */
    static int getRelationTypes( const std::string& uidContextObj,          /**< (I) The UID of the context object */
                                 const std::string& remoteObjType,          /**< (I) The tag of the remote object */
                                 const std::string& uidServiceProvider,     /**< (I) The UID of the service provider */
                                 std::vector<std::string>&relationNames     /**< (O) The list of relation names */
                                 );
    /**
        Retrieves the list of Relation Types from  a given context object UID, remote object and service provider UID.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p uidContextObject is invalid UID.
            <li>#CXPOM_invalid_tag if @p remoteObjectType is invalid type.
            <li>#CXPOM_invalid_tag if @p uidServiceProvider is invalid UID.
        </ul>
    */
    static int getRelationTypesTags( const std::string& uidContextObj,       /**< (I) The UID of the context object */
                                     const std::string& remoteObjType,       /**< (I) The remote object type */
                                     const std::string& uidServiceProvider,  /**< (I) The UID of the Service Provider */
                                     std::vector< tag_t >&relationNames      /**< (O) The list of relation names */
                                     );
    /**
        Retrieves the list of relations from a given service provider, primary and remote objects.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag  if @p serviceProviderType is invalid type.
            <li>#CXPOM_invalid_tag  if @p primaryObjType is invalid type.
            <li>#CXPOM_invalid_tag  if @p remoteObjectType is invalid type.
        </ul>
    */
    static int queryAllRelationTypeRevise2( const tag_t serviceProviderType,       /**< (I) The service provider type */
                                            const tag_t primaryObjType,            /**< (I) The primary object type */
                                            const std::string& remoteObjectType,   /**< (I) The remote object type */
                                            std::vector<tag_t>&relationNames       /**< (O) The list of relation names */
                                            );
    /**
        Checks that the relation names exist for a given service provider, primary and remote objects.
        <br/>It also retrieves the list of Relation types.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p serviceProviderType is invalid type.
            <li>#CXPOM_invalid_tag if @p primaryObjType is invalid type.
            <li>#CXPOM_invalid_tag if @p remoteObjectType is invalid type.
        </ul>
    */
    static int queryAllRelationTypeRevise( const tag_t serviceProviderType,      /**< (I) The service provider type */
                                           const tag_t primaryObjType,           /**< (I) The primary object type */
                                           const std::string &remoteObjectType,  /**< (I) The remote object type */
                                           std::vector<tag_t>&relationNames,     /**< (O) The list of relation */
                                           bool& isRelTypeExist                  /**< (O) The relation type exist */
                                           );
    /**
        Retrieves the list of supported primary objects from a given service provider type and remote object type.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p serviceProvider is invalid type.
            <li>#CXPOM_invalid_tag if @p remoteObject is invalid type.
        </ul>
    */
    static int findAllPrimaryObjForRemoteObj( const tag_t serviceProviderType,                   /**< (I) The service provider */
                                              const std::string& remoteObjectType,               /**< (I) The remote object */
                                              std::vector<tag_t> &supportedPrimaryObjTypes       /**< (O) The list of supported primary object */
                                              );
    /**
        Retrieves the list of matched primary objects from a given primary type.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#CXPOM_invalid_tag if @p primaryObjType is invalid type.
            <li>#CXPOM_invalid_tag if @p supportedPrimaryObjTypes are invalid types.
        </ul>
    */
    static int findExactMatchOfPrimaryObjectList( const tag_t primaryObjType,                              /**< (I) The type tag of primary object */
                                                  const std::vector<tag_t > &supportedPrimaryObjTypes,     /**< (I) The list of supported primary object types */
                                                  std::vector<tag_t>& exactListOfprimaryObjTypes           /**< (O) The list of exact primary object types */
                                                  );

    /**
        Retrieves SSO parameters from the rootservice response.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseString has invalid structure.
        </ul>
    */
    static int getSSOParamsFromRootsvc(  const std::string &responseString, /**< (I) Rootservice response string. */
                                          std::string &ssoAppId, /**< (O) AppID parameter. */
                                          std::string &ssoSvcUrl /**< (O) Service URL parameter. */ );
    /**
        Retrieves Access,Request and Auhtorization Tokens Url parameters from the rootservice response.
        @returns
        <ul>
            <li>#ITK_ok on success
            <li>#LIS0LISFMWRK_invalid_http_response if @p responseString has invalid structure.
        </ul>
    */
    static int getAuthorizationURLFromRootServices( const std::string& responseString,      /**< (I) Rootservice response string */
                                                    std::string&accessTokenUrl,             /**< (0) AccessTokenUrl */
                                                    std::string& requestTokenUrl,           /**< (0) RequestTokenUrl */
                                                    std::string& userAuthorizaitonUrl,      /**< (0) UserAuthorizationUrl */
                                                    std::string &consumerKeyUrl);           /**< (0) ConsumerKeyUrl */

private:

};
/** @} */
#include <Lis0lisfmwrk/libLis0lisfmwrk_undef.h>
#endif
