/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "guacamole/mem.h"

#include <stddef.h>
#include <stdio.h>
#include <string.h>

/**
 * Returns the space remaining in a buffer assuming that the given number of
 * bytes have already been written. If the number of bytes exceeds the size
 * of the buffer, zero is returned.
 *
 * @param n
 *     The size of the buffer in bytes.
 *
 * @param length
 *     The number of bytes which have been written to the buffer so far. If
 *     the routine writing the bytes will automatically truncate its writes,
 *     this value may exceed the size of the buffer.
 *
 * @return
 *     The number of bytes remaining in the buffer. This value will always
 *     be non-negative. If the number of bytes written already exceeds the
 *     size of the buffer, zero will be returned.
 */
#define REMAINING(n, length) (((n) < (length)) ? 0 : ((n) - (length)))

int guac_itoa(char* restrict dest, int integer) {

    /* Determine size of string. */
    int str_size = snprintf(dest, 0, "%i", integer);

    /* If an error occurs, just return that and skip the conversion. */
    if (str_size < 0)
        return str_size;

    /* Do the conversion and return. */
    return snprintf(dest, (str_size + 1), "%i", integer);

}

int guac_itoa_safe(char* restrict dest, size_t dest_size, int integer)
{
    int str_size = snprintf(dest, dest_size, "%d", integer);

    if (str_size < 0)
        return str_size;

    /* Return an error if the string was truncated. */
    if ((size_t)str_size >= dest_size)
        return -1;

    /* Return the number of characters written (excluding the terminator). */
    return str_size;
}

size_t guac_strlcpy(char* restrict dest, const char* restrict src, size_t n) {

#ifdef HAVE_STRLCPY
    return strlcpy(dest, src, n);
#else
    /* Calculate actual length of desired string */
    size_t length = strlen(src);

    /* Copy nothing if there is no space */
    if (n == 0)
        return length;

    /* Calculate length of the string which will be copied */
    size_t copy_length = length;
    if (copy_length >= n)
        copy_length = n - 1;

    /* Copy only as much of string as possible, manually adding a null
     * terminator */
    memcpy(dest, src, copy_length);
    dest[copy_length] = '\0';

    /* Return the overall length of the desired string */
    return length;
#endif

}

size_t guac_strlcat(char* restrict dest, const char* restrict src, size_t n) {

#ifdef HAVE_STRLCPY
    return strlcat(dest, src, n);
#else
    size_t length = strnlen(dest, n);
    return length + guac_strlcpy(dest + length, src, REMAINING(n, length));
#endif

}

char* guac_strnstr(const char *haystack, const char *needle, size_t len) {

#ifdef HAVE_STRNSTR
    return strnstr(haystack, needle, len);
#else
    const char* chr;
    size_t nlen = strlen(needle);

    /* Follow documented API: return haystack if needle is the empty string. */
    if (nlen == 0)
        return (char*) haystack;

    /* Use memchr to find candidates. It might be optimized in asm. */
    for (size_t off = 0; off < len
            && NULL != (chr = memchr(haystack + off, needle[0], len - off)); off++) {

        /* chr is guaranteed to be in bounds of and >= haystack. */
        off = chr - haystack;

        /* If needle would go beyond provided len, it doesn't exist in haystack. */
        if (off + nlen > len)
            return NULL;

        /* Now that we know we have at least nlen bytes, compare them. */
        if (!memcmp(chr, needle, nlen))
            return (char*) chr;

    }

    /* memchr ran out of candidates, needle wasn't found. */
    return NULL;
#endif

}

char* guac_strndup(const char* str, size_t n) {

    /* Return NULL if no string provided */
    if (str == NULL)
        return NULL;

    /* Do not attempt to duplicate if the length is somehow magically so
     * obscenely large that it will not be possible to add a null terminator */
    size_t length;
    size_t length_to_copy = strnlen(str, n);
    if (guac_mem_ckd_add(&length, length_to_copy, 1))
        return NULL;

    /* Otherwise just copy to a new string in same manner as strndup() */
    char* new_str = (char*)guac_mem_alloc(length);
    if (new_str != NULL) {
        memcpy(new_str, str, length_to_copy);
        new_str[length_to_copy] = '\0';
    }

    return new_str;

}

char* guac_strdup(const char* str) {

    /* Return NULL if no string provided */
    if (str == NULL)
        return NULL;

    return guac_strndup(str, strlen(str));
}

size_t guac_strljoin(char* restrict dest, const char* restrict const* elements,
        int nmemb, const char* restrict delim, size_t n) {

    size_t length = 0;
    const char* restrict const* current = elements;

    /* If no elements are provided, nothing to do but ensure the destination
     * buffer is null terminated */
    if (nmemb <= 0)
        return guac_strlcpy(dest, "", n);

    /* Initialize destination buffer with first element */
    length += guac_strlcpy(dest, *current, n);

    /* Copy all remaining elements, separated by delimiter */
    for (current++; nmemb > 1; current++, nmemb--) {
        length += guac_strlcat(dest + length, delim, REMAINING(n, length));
        length += guac_strlcat(dest + length, *current, REMAINING(n, length));
    }

    return length;

}
