/* ****************************************************************************
*
* getEntityByIdAttributeByName -
*
* GET /v1/registry/contextEntities/{entityId::id}/attributes/{attributeName}
* GET /ngsi9/contextEntities/{entityId::id}/attributes/{attributeName}
*
* Payload In:  None
* Payload Out: DiscoverContextAvailabilityResponse
*/
std::string getEntityByIdAttributeByName
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  std::string                          entityId      = (compV.size() == 6)? compV[3] : compV[2];
  std::string                          attributeName = (compV.size() == 6)? compV[5] : compV[4];
  std::string                          answer;

  //
  // 1. Fill in parseDataP->dcar.res to pass to postDiscoverContextAvailability
  //
  EntityId                             eId(entityId, "", "");
  std::vector<std::string>             attributeV;
  Restriction                          restriction;

  attributeV.push_back(attributeName);

  parseDataP->dcar.res.fill(eId, attributeV, restriction);


  //
  // 2. Call the standard operation
  //
  answer = postDiscoverContextAvailability(ciP, components, compV, parseDataP);

  return answer;
}
/* ****************************************************************************
*
* getContextEntitiesByEntityIdAndType - 
*
* GET /v1/registry/contextEntities/type/{ETYPE}/id/{EID}
*
* 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, esist, !exist)
* 02. Check validity of URI params
* 03. Fill in DiscoverContextAvailabilityRequest
* 04. Call standard operation postDiscoverContextAvailability
* 05. Cleanup and return result
*/
std::string getContextEntitiesByEntityIdAndType
(
  ConnectionInfo*            ciP,
  int                        components,
  std::vector<std::string>&  compV,
  ParseData*                 parseDataP
)
{
  std::string                          entityType              = compV[4];
  std::string                          entityId                = compV[6];
  std::string                          entityTypeFromUriParam  = ciP->uriParam[URI_PARAM_ENTITY_TYPE];
  EntityTypeInfo                       typeInfo                = EntityTypeEmptyOrNotEmpty;
  std::string                          answer;
  DiscoverContextAvailabilityResponse  response;


  // 01. Get values from URL (entityId::type, esist, !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 DiscoverContextAvailabilityRequest
  // 04. Call standard operation postDiscoverContextAvailability
  //
  if (typeInfo == EntityTypeEmpty)
  {
    parseDataP->dcars.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->dcars.res.render(ContextEntitiesByEntityIdAndType, ""));
  }
  else if ((entityTypeFromUriParam != entityType) && (entityTypeFromUriParam != ""))
  {
    parseDataP->dcars.res.errorCode.fill(SccBadRequest, "non-matching entity::types in URL");
    alarmMgr.badInput(clientIp, "non-matching entity::types in URL");

    TIMED_RENDER(answer = parseDataP->dcars.res.render(ContextEntitiesByEntityIdAndType, ""));
  }
  else
  {
    // 03. Fill in DiscoverContextAvailabilityRequest
    parseDataP->dcar.res.fill(entityId, entityType);

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

  // 05. Cleanup and return result
  parseDataP->dcar.res.release();
  parseDataP->dcars.res.release();

  return answer;
}