bool get_address_set(const char *pAddress, addressSet_t* outAddress)
{
    if (NULL == pAddress)
    {
        printf("parameter is null !\n");
        return false;
    }

    size_t len = strlen(pAddress);
    bool isIp = false;
    size_t ipLen = 0;

    for (size_t i = 0; i < len; i++)
    {
        if (pAddress[i] == '.')
        {
            isIp = true;
        }

        // found port number start index
        if (isIp && pAddress[i] == ':')
        {
            ipLen = i;
            break;
        }
    }

    if (isIp)
    {
        if(ipLen && ipLen < sizeof(outAddress->ipAddress))
        {
            OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
                             pAddress, ipLen);
        }
        else if (!ipLen && len < sizeof(outAddress->ipAddress))
        {
            OICStrcpyPartial(outAddress->ipAddress, sizeof(outAddress->ipAddress),
                             pAddress, len);
        }
        else
        {
            printf("IP Address too long: %zu\n", (ipLen == 0) ? len : ipLen);
            return false;
        }

        if (ipLen > 0)
        {
            outAddress->port = atoi(pAddress + ipLen + 1);
        }
        return true;
    }
    else
    {
        return false;
    }
}
void get_resource_uri(char *URI, char *resourceURI, int length)
{
    char *startPos = URI;
    char *temp = NULL;
    if (NULL != (temp = strstr(URI, "://")))
    {
        startPos = strchr(temp + 3, '/');
        if (!startPos)
        {
            printf("Resource URI is missing\n");
            return;
        }
    }

    char *endPos = strchr(startPos, '?');
    if (!endPos)
    {
        endPos = URI + strlen(URI);
    }
    endPos -= 1;

    if (endPos - startPos <= length)
    {
        OICStrcpyPartial(resourceURI, length, startPos + 1, endPos - startPos);
    }

    printf("URI: %s, ResourceURI:%s\n", URI, resourceURI);
}
// Tests a partial copy where the source length parameter is longer
// than the string length
TEST(StringTests, StrcpyPartialLongerSourceLen)
{
    char target[10];
    memset(target, SENTINEL_VALUE, sizeof(target));
    char source[] = "123456789";

    char* result = OICStrcpyPartial(target, sizeof(target), source, 99);

    EXPECT_EQ(target, result);
    EXPECT_EQ(sizeof(target) - 1, strlen(target));
    EXPECT_STREQ(source, result);
}
// Tests a partial copy where the source length is zero
TEST(StringTests, StrcpyPartialZeroSourceLen)
{
    char target[10];
    memset(target, SENTINEL_VALUE, sizeof(target));
    char source[] = "123456789";

    char* result = OICStrcpyPartial(target, sizeof(target), source, 0);

    EXPECT_EQ(target, result);

    for(size_t i = 0; i < sizeof(target); ++i)
    {
        EXPECT_EQ(SENTINEL_VALUE, target[i]);
    }
}
// Tests a partial copy where the source length parameter is shorter
// than the string length
TEST(StringTests, StrcpyPartialShorterSourceLen)
{
    char target[10];
    memset(target, SENTINEL_VALUE, sizeof(target));
    char source[] = "123456789";

    char* result = OICStrcpyPartial(target, sizeof(target), source, strlen(source) - 5);

    EXPECT_EQ(target, result);
    EXPECT_EQ(strlen(source) - 5, strlen(target));
    EXPECT_STREQ("1234", result);

    for(size_t i = strlen(target) + 1; i< sizeof(target); ++i)
    {
        EXPECT_EQ(SENTINEL_VALUE, result[i]);
    }
}
void send_response(const CAEndpoint_t *endpoint, const CAInfo_t *info)
{
    printf("entering send_response\n");

    printf("\n=============================================\n");
    printf("\tselect message type\n");
    printf("CON     : 0\n");
    printf("NON     : 1\n");
    printf("ACK     : 2\n");
    printf("RESET   : 3\n");
    printf("select : ");

    char buf[MAX_BUF_LEN] = { 0 };
    if (CA_STATUS_OK != get_input_data(buf, MAX_BUF_LEN))
    {
        return;
    }

    int messageType = buf[0] - '0';
    if (0 > messageType || 3 < messageType)
    {
        printf("Invalid message type\n");
        return;
    }

    int responseCode = 0 ;
    char responseCodeBuf[MAX_BUF_LEN] = { 0 };
    if (CA_MSG_RESET != messageType)
    {
        printf("\n=============================================\n");
        printf("\tselect response code\n");
        printf("EMPTY                    :   0\n");
        printf("SUCCESS                  : 200\n");
        printf("CREATED                  : 201\n");
        printf("DELETED                  : 202\n");
        printf("VALID                    : 203\n");
        printf("CHANGED                  : 204\n");
        printf("CONTENT                  : 205\n");
        printf("BAD_REQ                  : 400\n");
        printf("BAD_OPT                  : 402\n");
        printf("NOT_FOUND                : 404\n");
        printf("INTERNAL_SERVER_ERROR    : 500\n");
        printf("RETRANSMIT_TIMEOUT       : 504\n");
        printf("select : ");

        if (CA_STATUS_OK != get_input_data(responseCodeBuf, MAX_BUF_LEN))
        {
            return;
        }
        responseCode = atoi(responseCodeBuf);
    }

    // create response data
    uint16_t messageId = (info != NULL) ? info->messageId : 0;
    CAURI_t resourceUri = (info != NULL) ? info->resourceUri : 0;

    CAInfo_t responseData = { .type = messageType,
                              .messageId = messageId,
                              .token = NULL,
                              .tokenLength = 0,
                              .options = NULL,
                              .numOptions = 0,
                              .payload = NULL,
                              .payloadSize = 0,
                              .resourceUri = resourceUri };

    if(CA_MSG_RESET != messageType)
    {
        responseData.token = (info != NULL) ? info->token : NULL;
        responseData.tokenLength = (info != NULL) ? info->tokenLength : 0;

        if (endpoint->flags & CA_SECURE)
        {
            if(!responseData.resourceUri)
            {
               printf("resourceUri not available in SECURE\n");
               return;
            }
            printf("Sending response on secure communication\n");

            uint32_t length = sizeof(SECURE_INFO_DATA) + strlen(responseData.resourceUri);
            responseData.payload = (CAPayload_t) calloc(length,  sizeof(char));
            if (NULL == responseData.payload)
            {
                printf("Memory allocation fail\n");
                return;
            }
            snprintf((char *) responseData.payload, length, SECURE_INFO_DATA,
                     (const char *) responseData.resourceUri, g_local_secure_port);
            responseData.payloadSize = length;
        }
        else
        {
            printf("Sending response on non-secure communication\n");

            bool useBigPayload = select_payload_type();
            if (useBigPayload)
            {
                size_t payloadLength = 0;
                CAPayload_t binaryPayload = get_binary_payload(&payloadLength);
                if (NULL == binaryPayload)
                {
                    free(binaryPayload);
                    return;
                }

                responseData.payload = (CAPayload_t) malloc(payloadLength);
                if (NULL == responseData.payload)
                {
                    printf("Memory allocation failed!");
                    free(binaryPayload);
                    return;
                }
                memcpy(responseData.payload, binaryPayload, payloadLength);
                responseData.payloadSize = payloadLength;

                // memory free
                free(binaryPayload);
            }
            else
            {
                if(!responseData.resourceUri)
                {
                   printf("resourceUri not available in NON-SECURE\n");
                   return;
                }
                uint32_t length = sizeof(NORMAL_INFO_DATA) + strlen(responseData.resourceUri);
                responseData.payload = (CAPayload_t) calloc(length, sizeof(char));
                if (NULL == responseData.payload)
                {
                    printf("Memory allocation fail\n");
                    return;
                }
                snprintf((char *) responseData.payload, length, NORMAL_INFO_DATA,
                         (const char *) responseData.resourceUri);
                responseData.payloadSize = length;
            }
        }
    }

    CAResponseInfo_t responseInfo = { .result = responseCode,
                                      .info = responseData };

    // send response (transportType from remoteEndpoint of request Info)
    CAResult_t res = CASendResponse(endpoint, &responseInfo);
    if (CA_STATUS_OK != res)
    {
        printf("Send response error\n");
    }
    else
    {
        printf("Send response success\n");
    }

    if (responseData.payload)
    {
        free(responseData.payload);
    }

    printf("=============================================\n");
}

int get_secure_information(CAPayload_t payLoad)
{
    printf("Entering get_secure_information\n");

    if (!payLoad)
    {
        printf("Payload is NULL\n");
        return -1;
    }

    char *subString = NULL;
    if (NULL == (subString = strstr((const char *) payLoad, "\"sec\":1")))
    {
        printf("This is not secure resource\n");
        return -1;
    }

    if (NULL == (subString = strstr((const char *) payLoad, "\"port\":")))
    {
        printf("This secure resource does not have port information\n");
        return -1;
    }

    char *startPos = strstr(subString, ":");
    if (!startPos)
    {
        printf("Parsing failed !\n");
        return -1;
    }

    char *endPos = strstr(startPos, "}");
    if (!endPos)
    {
        printf("Parsing failed !\n");
        return -1;
    }

    char portStr[6] = {0};
    OICStrcpyPartial(portStr, sizeof(portStr), startPos + 1, (endPos - 1) - startPos);
    printf("secured port is: %s\n", portStr);
    return atoi(portStr);
}