#ifndef TEAMCENTER_BULK_PROPERTY_CONTEXT_DATA_HXX
#define TEAMCENTER_BULK_PROPERTY_CONTEXT_DATA_HXX

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

/**
    \@file BulkPropertyContextData.hxx

    \@brief Teamcenter::Property::BulkPropertyContextData include file
*/

#include <unidefs.h>
#include <tccore/method.h>
#include <common/tc_deprecation_macros.h>

#include <property/libproperty_exports.h>

namespace Teamcenter
{

namespace Property
{
/**
    This is an abstract class from which users will derive their own bulk property context data class.
*/
class PROPERTY_API BulkPropertyContextData
{

public:

    virtual ~BulkPropertyContextData() = 0;

};

}       //namespace Property
}       //namespace Teamcenter

/**
    Bulk load function pointer registered by external system.
    <br>If you require to cache information obtained in the execution of this function you should
    instantiate an appropriate subclass of BulkPropertyContextData to store that information and
    output it in the bulkContextData parameter.
    <br>The bulk property loader function may be invoked multiple times for batches of tags. A new
    BulkPropertyContextData should only be instantiated on the first call, when *bulkContextData is
    passed as null; on subsequent calls the previously created bulkContextData will be passed back
    in, your BulkPropertyContextData implementation must reuse that and provide a method to append
    the data generated on this pass to that which was cached earlier. For example use something like
    the following pattern in your function implementation:
    @code
    YourBulkPropertyContextData* yourContextData = 0;
    if ( *bulkContextData == 0 )
    {
        yourContextData = new YourBulkPropertyContextData();
        *bulkContextData = yourContextData;
    }
    else
    {
        yourContextData = dynamic_cast<YourBulkPropertyContextData*>( *bulkContextData );
        if ( yourContextData == 0 )
        {
            log_error( "<function> given BulkPropertyContextData that is not a YourBulkPropertyContextData" );
        }
    }
    yourContextData->append( someData );
    @endcode
*/
typedef void (*BulkProperty_bulk_loader_t)(
    tag_t               prop_desc_tags,                                     /**< (I) tags of the property descriptors */
    int                 n_tags,                                             /**< (I) No of object tag */
    const tag_t*        tags,                                               /**< (I) Object tags */
    Teamcenter::Property::BulkPropertyContextData**   bulk_context_data     /**< (IO) context data */
);

/**
    BulkOperation function pointer
*/

typedef void (*BulkOperation_bulk_loader_t)(
    const char*                                       operation_id,         /**< (I) Operation ID */
    int                                               n_tags,               /**< (I) Number of object tag */
    const tag_t*                                      tags,                 /**< (I) n_tags object tags */
    Teamcenter::Property::BulkPropertyContextData**   bulk_context_data     /**< (O) Context data */
);
/**
    Query-based bulk property loader function pointer registered by external system.
    Perform set-based query to retrieve attribute values from db
    Does property-specific computation if applicable
    Populate property values to Singleton PVM managing an array of buckets per type, e.g. Item Bucket,  ItemRevision Bucket and BOMLine Bucket
*/
typedef void (*BulkProperty_query_based_bulk_loader_t)(
    int n_property_descriptor_tags,         /** < (I) Number of property descriptors */
    const tag_t* property_descriptor_tags,  /** < (I) n_property_descriptor_tags The property descriptors */
    int   n_objects,                        /** < (I) Number of objects */
    const tag_t*   objects                  /** < (I) n_objects The objects */
    );

/**
    @deprecated #PROPDESC_register_bulk_loader deprecated in Teamcenter 11.3. Use #PROPDESC_register_bulk_loader2 instead.

    Registers bulk load function pointer and other information.
    @returns
    <ul>
    <li>ITK_ok on success
    <li>PROP_not_found if property descriptor not found
    </ul>

*/
TC_DEPRECATED( "11.3", "PROPDESC_register_bulk_loader", "PROPDESC_register_bulk_loader2" )
extern PROPERTY_API int PROPDESC_register_bulk_loader(
    tag_t prop_desc_tag,                        /**< (I) tag of the property descriptor */
    logical invoke_once,                        /**< (I) if batch function needs to invoke once */
    BulkProperty_bulk_loader_t bulk_loader_fn   /**< (I) batch function */
    );

/**
    Registers bulk load function pointer and other information.
    <br>The implementation of bulk_loader_fn must be capable of being invoked multiple times to
    build up the full result. Please refer to the documentation of #BulkProperty_bulk_loader_t for
    further information.

    @returns
    <ul>
    <li>ITK_ok on success
    <li>PROP_not_found if property descriptor not found
    </ul>
*/
extern PROPERTY_API int PROPDESC_register_bulk_loader2(
    tag_t prop_desc_tag,                        /**< (I) tag of the property descriptor */
    logical invoke_once,                        /**< (I) if batch function needs to invoke once */
    BulkProperty_bulk_loader_t bulk_loader_fn   /**< (I) batch function */
    );

/**
    Registers query based bulk load function pointer and other information.

    @returns
    <ul>
    <li>ITK_ok on success
    <li>PROP_not_found if property descriptor not found
    </ul>
*/
extern PROPERTY_API int PROPDESC_register_query_based_bulk_loader(
    int n_property_descriptor_tags,                                 /**< (I) Number of property descriptors */
    const tag_t* property_descriptor_tags,                          /**< (I) n_property_descriptors The property descriptors */
    BulkProperty_query_based_bulk_loader_t query_based_loader_fn    /**< (I) query based function */
);

/**
    Checks if property bulk loading context is active.
    @returns
    <ul>
    <li>true if in bulk context
    <li>false if not in bulk context
    </ul>
*/
extern PROPERTY_API logical PROPDESC_is_bulk_loading_context();

/**
    Retrieves the current user bulk property context.
    Returns bulk property context data class instance.

*/
extern PROPERTY_API Teamcenter::Property::BulkPropertyContextData* PROPDESC_ask_bulk_prop_context_data(
    METHOD_message_t* m                         /**< (I) method message */
    );

/**
    Retrieves the bulk property context for input business object and property.
    Returns bulk property context data class instance.
*/
extern PROPERTY_API Teamcenter::Property::BulkPropertyContextData* PROPDESC_ask_bulk_prop_context_data_by_name(
    tag_t objTag, const char* propName
    );

/**
    Executes registered bulk load function for each input property.

    @returns
    <ul>
    <li>ITK_ok on success
    <li>PROP_not_found, if the given property descriptor tag is invalid.
    <li>Potentially other errors
    </ul>
*/
extern PROPERTY_API int PROPDESC_execute_bulk_loader(
    int n_tags,                                 /**< (I) Number of input objects */
    const tag_t* tags,                          /**< (I) n_tags Input objects */
    int n_props,                                /**< (I) Number of input properties */
    const char** props                          /**< (I) n_props Input property names */
    );

/**
    Retrieves the bulk property context data instance for the given property name.
    <br>The bulk property context data instance may be created during execution of #BulkProperty_bulk_loader_t
    bulk loader batch function to cache information that can be used later. The function may be called from the
    property getter function.

    @code
    if( PROPDESC_is_bulk_loading_context() )
    {
        MyBulkPropertyContextData* myBulkPropertyContextData =
            static_cast<MyBulkPropertyContextData *> (PROPDESC_ask_bulk_prop_context_data_by_name( objTag, "myPropName" ));

        if( myBulkPropertyContextData != 0 )
        {
            // implemenattion
        }
    }
    @endcode

    @returns
    <ul>
    <li>BulkPropertyContextData bulk property context data class instance on success
    </ul>
*/
extern PROPERTY_API Teamcenter::Property::BulkPropertyContextData* PROPDESC_ask_bulk_prop_context_data_by_name( 
    tag_t objTag, const char* propName 
    );

/**
    Retrieves the bulk property context data instance for the given property descriptor.
    <br>The bulk property context data instance may be created during execution of #BulkProperty_bulk_loader_t
    bulk loader batch function to cache information that can be used later. The function may be called from the
    property getter function.

    @code
    BulkPropertyContextData* myBulkPropertyContextData = PROPDESC_ask_bulk_prop_context_data_by_name( pdTag );
    if( myBulkPropertyContextData != 0 )
    {
        // implementation
    }
    @endcode

    @returns
    <ul>
    <li>BulkPropertyContextData bulk property context data class instance if bulk loading context is active
    <li>NULL if bulk loading context is not active
    </ul>
*/
extern PROPERTY_API Teamcenter::Property::BulkPropertyContextData* PROPDESC_ask_bulk_prop_context_data( 
    tag_t pdTag     /**< (I) property descriptor tag */ 
    );


#include <property/libproperty_undef.h>
#endif //TEAMCENTER_BULK_PROPERTY_CONTEXT_DATA_HXX
