/* ****************************************************************************
*
* postContextEntityAttributes - 
*
* POST /ngsi9/contextEntities/{entityId}/attributes
*/
std::string postContextEntityAttributes(ConnectionInfo* ciP, int components, std::vector<std::string> compV, ParseData* parseDataP)
{
  std::string              entityId = compV[2];

  // Transform RegisterProviderRequest into RegisterContextRequest
  parseDataP->rcr.res.fill(parseDataP->rpr.res, entityId, "", "");

  // Now call postRegisterContext (postRegisterContext doesn't use the parameters 'components' and 'compV')
  std::string answer = postRegisterContext(ciP, components, compV, parseDataP);
  parseDataP->rpr.res.release();
  parseDataP->rcr.res.release();

  return answer;
}
/* ****************************************************************************
*
* postContextEntityAttributes -
*
* POST /v1/registry/contextEntities/{entityId}/attributes
* POST /ngsi9/contextEntities/{entityId}/attributes
*
* Payload In:  RegisterProviderRequest
* Payload Out: RegisterContextResponse
*
* 1. Transform RegisterProviderRequest+entityId into a RegisterContextRequest
* 2. Call the Standard operation for RegisterContextRequest
*/
std::string postContextEntityAttributes
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  std::string  entityId = (compV[0] == "v1")? compV[3] : compV[2];
  std::string  answer;

  parseDataP->rcr.res.fill(parseDataP->rpr.res, entityId, "", "");
  answer = postRegisterContext(ciP, components, compV, parseDataP);

  parseDataP->rpr.res.release();
  parseDataP->rcr.res.release();

  return answer;
}
/* ****************************************************************************
*
* postContextEntityTypeAttribute -
*
* POST /ngsi9/contextEntityTypes/{typeName}/attributes/{attributeName}
*/
std::string postContextEntityTypeAttribute
(
    ConnectionInfo*            ciP,
    int                        components,
    std::vector<std::string>&  compV,
    ParseData*                 parseDataP
)
{
    std::string  entityIdType   = (compV[0] == "v1")? compV[3] : compV[2];
    std::string  attributeName  = (compV[0] == "v1")? compV[5] : compV[4];

    // Transform RegisterProviderRequest into RegisterContextRequest
    parseDataP->rcr.res.fill(parseDataP->rpr.res, "", entityIdType, attributeName);

    // Now call postRegisterContext (postRegisterContext doesn't use the parameters 'components' and 'compV')
    std::string answer = postRegisterContext(ciP, components, compV, parseDataP);
    parseDataP->rcr.res.release();

    return answer;
}
/* ****************************************************************************
*
* postEntityByIdAttributeByNameWithTypeAndId - 
*
* POST /v1/registry/contextEntities/type/{entity::type}/id/{entity::id}/attributes/{attribute::name}
*
* Payload In:  RegisterProviderRequest
* Payload Out: RegisterContextResponse
*
* URI parameters:
*   - entity::type=XXX     (must coincide with entity::type in URL)
*   - !exist=entity::type  (if set - error -- entity::type cannot be empty)
*   - exist=entity::type   (not supported - ok if present, ok if not present ...)
*
* 01. Get values from URL (entityId::type, exist, !exist)
* 02. Check validity of URI params
* 03. Fill in RegisterContextRequest
* 04. Call standard operation postRegisterContext
* 05. Cleanup and return result
*/
std::string postEntityByIdAttributeByNameWithTypeAndId
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  std::string     entityType              = compV[4];
  std::string     entityId                = compV[6];
  std::string     attributeName           = compV[8];
  std::string     entityTypeFromUriParam  = ciP->uriParam[URI_PARAM_ENTITY_TYPE];
  EntityTypeInfo  typeInfo                = EntityTypeEmptyOrNotEmpty;
  std::string     answer;


  // 01. Get values from URL (entityId::type, exist, !exist)
  if (ciP->uriParam[URI_PARAM_NOT_EXIST] == URI_PARAM_ENTITY_TYPE)
  {
    typeInfo = EntityTypeEmpty;
  }
  else if (ciP->uriParam[URI_PARAM_EXIST] == URI_PARAM_ENTITY_TYPE)
  {
    typeInfo = EntityTypeNotEmpty;
  }


  //
  // 02. Check validity of URI params ...
  //     and if OK:
  // 03. Fill in RegisterContextRequest
  // 04. Call standard operation postRegisterContext
  //
  if (typeInfo == EntityTypeEmpty)
  {
    parseDataP->rcrs.res.errorCode.fill(SccBadRequest, "entity::type cannot be empty for this request");
    alarmMgr.badInput(clientIp, "entity::type cannot be empty for this request");

    TIMED_RENDER(answer = parseDataP->rcrs.res.render(IndividualContextEntityAttributeWithTypeAndId, ciP->outFormat, ""));
  }
  else if ((entityTypeFromUriParam != entityType) && (entityTypeFromUriParam != ""))
  {
    parseDataP->rcrs.res.errorCode.fill(SccBadRequest, "non-matching entity::types in URL");
    alarmMgr.badInput(clientIp, "non-matching entity::types in URL");

    TIMED_RENDER(answer = parseDataP->rcrs.res.render(IndividualContextEntityAttributeWithTypeAndId, ciP->outFormat, ""));
  }
  else
  {
    // 03. Fill in RegisterContextRequest
    parseDataP->rcr.res.fill(parseDataP->rpr.res, entityId, entityType, attributeName);

    // 04. Call standard operation postRegisterContext
    answer = postRegisterContext(ciP, components, compV, parseDataP);
  }


  // 05. Cleanup and return result
  parseDataP->rpr.res.release();
  parseDataP->rcr.res.release();

  return answer;
}