/*
**  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.
*/

#ifndef APREQ_UTIL_H
#define APREQ_UTIL_H

#include "apr_file_io.h"
#include "apr_buckets.h"
#include "apreq.h"

#ifdef  __cplusplus
 extern "C" {
#endif

/**
 * This header contains useful functions for creating new
 * parsers, hooks or modules.  It includes
 *
 *    - string <-> array converters
 *    - substring search functions
 *    - simple encoders & decoders for urlencoded strings
 *    - simple time, date, & file-size converters
 * @file apreq_util.h
 * @brief Utility functions for apreq.
 * @ingroup libapreq2
 */

/**
 * Join an array of values. The result is an empty string if there are
 * no values.
 *
 * @param p    Pool to allocate return value.
 * @param sep  String that is inserted between the joined values.
 * @param arr  Array of apreq_value_t entries.
 * @param mode Join type- see apreq_join_t.
 *
 * @return Joined string, or NULL on error
 */
APREQ_DECLARE(char *) apreq_join(apr_pool_t *p,
                                 const char *sep,
                                 const apr_array_header_t *arr,
                                 apreq_join_t mode);

/**
 * Returns offset of match string's location, or -1 if no match is found.
 *
 * @param hay  Location of bytes to scan.
 * @param hlen Number of bytes available for scanning.
 * @param ndl  Search string
 * @param nlen Length of search string.
 * @param type Match type.
 *
 * @return Offset of match string, or -1 if no match is found.
 *
 */
APREQ_DECLARE(apr_ssize_t) apreq_index(const char* hay, apr_size_t hlen,
                                       const char* ndl, apr_size_t nlen,
                                       const apreq_match_t type);

/**
 * Places a quoted copy of src into dest.  Embedded quotes are escaped with a
 * backslash ('\').
 *
 * @param dest Location of quoted copy.  Must be large enough to hold the copy
 *             and trailing null byte.
 * @param src  Original string.
 * @param slen Length of original string.
 * @param dest Destination string.
 *
 * @return length of quoted copy in dest.
 */
APREQ_DECLARE(apr_size_t) apreq_quote(char *dest, const char *src,
                                      const apr_size_t slen);

/**
 *
 * Same as apreq_quote() except when src begins and ends in quote marks. In
 * that case it assumes src is quoted correctly, and just copies src to dest.
 *
 * @param dest Location of quoted copy.  Must be large enough to hold the copy
 *             and trailing null byte.
 * @param src  Original string.
 * @param slen Length of original string.
 * @param dest Destination string.
 *
 * @return length of quoted copy in dest.
 */
APREQ_DECLARE(apr_size_t) apreq_quote_once(char *dest, const char *src,
                                           const apr_size_t slen);

/**
 * Url-encodes a string.
 *
 * @param dest Location of url-encoded result string. Caller must ensure it
 *             is large enough to hold the encoded string and trailing '\\0'.
 * @param src  Original string.
 * @param slen Length of original string.
 *
 * @return length of url-encoded string in dest; does not exceed 3 * slen.
 */
APREQ_DECLARE(apr_size_t) apreq_encode(char *dest, const char *src,
                                       const apr_size_t slen);

/**
 * Convert a string from cp1252 to utf8.  Caller must ensure it is large enough
 * to hold the encoded string and trailing '\\0'.
 *
 * @param dest Location of utf8-encoded result string. Caller must ensure it
 *             is large enough to hold the encoded string and trailing '\\0'.
 * @param src  Original string.
 * @param slen Length of original string.
 *
 * @return length of utf8-encoded string in dest; does not exceed 3 * slen.
 */
APREQ_DECLARE(apr_size_t) apreq_cp1252_to_utf8(char *dest,
                                               const char *src, apr_size_t slen);

/**
 * Heuristically determine the charset of a string.
 *
 * @param src  String to scan.
 * @param slen Length of string.
 *
 * @return APREQ_CHARSET_ASCII  if the string contains only 7-bit chars;
 * @return APREQ_CHARSET_UTF8   if the string is a valid utf8 byte sequence;
 * @return APREQ_CHARSET_LATIN1 if the string has no control chars;
 * @return APREQ_CHARSET_CP1252 if the string has control chars.
 */
APREQ_DECLARE(apreq_charset_t) apreq_charset_divine(const char *src,
                                                    apr_size_t slen);

/**
 * Url-decodes a string.
 *
 * @param dest Location of url-encoded result string. Caller must ensure dest is
 *             large enough to hold the encoded string and trailing null character.
 * @param dlen points to resultant length of url-decoded string in dest
 * @param src  Original string.
 * @param slen Length of original string.
 *
 * @return APR_SUCCESS.
 * @return APR_INCOMPLETE if the string
 *                        ends in the middle of an escape sequence.
 * @return ::APREQ_ERROR_BADSEQ or ::APREQ_ERROR_BADCHAR on malformed input.
 *
 * @remarks In the non-success case, dlen will be set to include
 *          the last succesfully decoded value.  This function decodes
 *          \%uXXXX into a utf8 (wide) character, following ECMA-262
 *          (the Javascript spec) Section B.2.1.
 */

APREQ_DECLARE(apr_status_t) apreq_decode(char *dest, apr_size_t *dlen,
                                         const char *src, apr_size_t slen);

/**
 * Url-decodes an iovec array.
 *
 * @param dest  Location of url-encoded result string. Caller must ensure dest is
 *              large enough to hold the encoded string and trailing null character.
 * @param dlen  Resultant length of dest.
 * @param v     Array of iovecs that represent the source string
 * @param nelts Number of iovecs in the array.
 *
 * @return APR_SUCCESS.
 * @return APR_INCOMPLETE if the iovec
 *                        ends in the middle of an escape sequence.
 * @return ::APREQ_ERROR_BADSEQ or ::APREQ_ERROR_BADCHAR on malformed input.
 *
 * @remarks In the non-APR_SUCCESS case, dlen will be set to include
 *          the last succesfully decoded value.  This function decodes
 *          \%uXXXX into a utf8 (wide) character, following ECMA-262
 *          (the Javascript spec) Section B.2.1.
 */

APREQ_DECLARE(apr_status_t) apreq_decodev(char *dest, apr_size_t *dlen,
                                          struct iovec *v, int nelts);

/**
 * Returns an url-encoded copy of a string.
 *
 * @param p    Pool used to allocate the return value.
 * @param src  Original string.
 * @param slen Length of original string.
 *
 * @return The url-encoded string.
 *
 * @remarks Use this function insead of apreq_encode if its
 *          caller might otherwise overflow dest.
 */
static APR_INLINE
char *apreq_escape(apr_pool_t *p, const char *src, const apr_size_t slen)
{
    char *rv;

    if (src == NULL)
        return NULL;

    rv = (char *)apr_palloc(p, 3 * slen + 1);
    apreq_encode(rv, src, slen);
    return rv;
}

/**
 * An \e in-situ url-decoder.
 *
 * @param str  The string to decode
 *
 * @return  Length of decoded string, or < 0 on error.
 */
static APR_INLINE apr_ssize_t apreq_unescape(char *str)
{
    apr_size_t len;
    apr_status_t rv = apreq_decode(str, &len, str, strlen(str));
    if (rv == APR_SUCCESS)
        return (apr_ssize_t)len;
    else
        return -1;
}

/**
 * Converts file sizes (KMG) to bytes
 *
 * @param s  file size matching m/^\\d+[KMG]b?$/i
 *
 * @return 64-bit integer representation of s.
 *
 * @todo What happens when s is malformed?  Should this return
 *       an unsigned value instead?
 */

APREQ_DECLARE(apr_int64_t) apreq_atoi64f(const char *s);

/**
 * Converts time strings (YMDhms) to seconds
 *
 * @param s time string matching m/^\\+?\\d+[YMDhms]$/
 *
 * @return 64-bit integer representation of s as seconds.
 *
 * @todo What happens when s is malformed?  Should this return
 *       an unsigned value instead?
 */

APREQ_DECLARE(apr_int64_t) apreq_atoi64t(const char *s);

/**
 * Writes brigade to a file.
 *
 * @param f       File that gets the brigade.
 * @param wlen    On a successful return, wlen holds the length of
 *                the brigade, which is the amount of data written to
 *                the file.
 * @param bb      Bucket brigade.
 *
 * @return APR_SUCCESS.
 * @return Error status code from either an unsuccessful apr_bucket_read(),
 *         or a failed apr_file_writev().
 *
 * @remarks       This function leaks a bucket brigade into bb->p whenever
 *                the final bucket in bb is a spool bucket.
 */

APREQ_DECLARE(apr_status_t) apreq_brigade_fwrite(apr_file_t *f,
                                                 apr_off_t *wlen,
                                                 apr_bucket_brigade *bb);
/**
 * Makes a temporary file.
 *
 * @param fp    Points to the temporary apr_file_t on success.
 * @param pool  Pool to associate with the temp file.  When the
 *              pool is destroyed, the temp file will be closed
 *              and deleted.
 * @param path  The base directory which will contain the temp file.
 *              If param == NULL, the directory will be selected via
 *              tempnam().  See the tempnam manpage for details.
 *
 * @return APR_SUCCESS.
 * @return Error status code from unsuccessful apr_filepath_merge(),
 *         or a failed apr_file_mktemp().
 */

APREQ_DECLARE(apr_status_t) apreq_file_mktemp(apr_file_t **fp,
                                              apr_pool_t *pool,
                                              const char *path);

/**
 * Set aside all buckets in the brigade.
 *
 * @param bb Brigade.
 * @param p  Setaside buckets into this pool.
 * @return APR_SUCCESS.
 * @return Error status code from an unsuccessful apr_bucket_setaside().
 */

static APR_INLINE
apr_status_t apreq_brigade_setaside(apr_bucket_brigade *bb, apr_pool_t *p)
{
    apr_bucket *e;
    for (e = APR_BRIGADE_FIRST(bb); e != APR_BRIGADE_SENTINEL(bb);
         e = APR_BUCKET_NEXT(e))
    {
        apr_status_t rv = apr_bucket_setaside(e, p);
        if (rv != APR_SUCCESS)
            return rv;
    }
    return APR_SUCCESS;
}


/**
 * Copy a brigade.
 *
 * @param d (destination) Copied buckets are appended to this brigade.
 * @param s (source) Brigade to copy from.
 *
 * @return APR_SUCCESS.
 * @return Error status code from an unsuccessful apr_bucket_copy().
 *
 * @remarks s == d produces Undefined Behavior.
 */

static APR_INLINE
apr_status_t apreq_brigade_copy(apr_bucket_brigade *d, apr_bucket_brigade *s) {
    apr_bucket *e;
    for (e = APR_BRIGADE_FIRST(s); e != APR_BRIGADE_SENTINEL(s);
         e = APR_BUCKET_NEXT(e))
    {
        apr_bucket *c;
        apr_status_t rv = apr_bucket_copy(e, &c);
        if (rv != APR_SUCCESS)
            return rv;

        APR_BRIGADE_INSERT_TAIL(d, c);
    }
    return APR_SUCCESS;
}

/**
 * Move the front of a brigade.
 *
 * @param d (destination) Append buckets to this brigade.
 * @param s (source) Brigade to take buckets from.
 * @param e First bucket of s after the move.  All buckets
 *          before e are appended to d.
 *
 * @remarks This moves all buckets when e == APR_BRIGADE_SENTINEL(s).
 */

static APR_INLINE
void apreq_brigade_move(apr_bucket_brigade *d, apr_bucket_brigade *s,
                        apr_bucket *e)
{
    apr_bucket *f;

    if (e != APR_BRIGADE_SENTINEL(s)) {
        f = APR_RING_FIRST(&s->list);
        if (f == e) /* zero buckets to be moved */
            return;

        /* obtain the last bucket to be moved */
        e = APR_RING_PREV(e, link);

        APR_RING_UNSPLICE(f, e, link);
        APR_RING_SPLICE_HEAD(&d->list, f, e, apr_bucket, link);
    }
    else {
        APR_BRIGADE_CONCAT(d, s);
    }
}


/**
 * Search a header string for the value of a particular named attribute.
 *
 * @param hdr Header string to scan.
 * @param name Name of attribute to search for.
 * @param nlen Length of name.
 * @param val Location of (first) matching value.
 * @param vlen Length of matching value.
 *
 * @return APR_SUCCESS.
 * @return ::APREQ_ERROR_NOATTR if the attribute is not found.
 * @return ::APREQ_ERROR_BADSEQ if an unpaired quote mark was detected.
 */
APREQ_DECLARE(apr_status_t) apreq_header_attribute(const char *hdr,
                                                   const char *name,
                                                   const apr_size_t nlen,
                                                   const char **val,
                                                   apr_size_t *vlen);


/**
 * Concatenates the brigades, spooling large brigades into
 * a tempfile (APREQ_SPOOL) bucket.
 *
 * @param pool           Pool for creating a tempfile bucket.
 * @param temp_dir       Directory for tempfile creation.
 * @param brigade_limit  If out's length would exceed this value,
 *                       the appended buckets get written to a tempfile.
 * @param out            Resulting brigade.
 * @param in             Brigade to append.
 *
 * @return APR_SUCCESS.
 * @return Error status code resulting from either apr_brigade_length(),
 *         apreq_file_mktemp(), apreq_brigade_fwrite(), or apr_file_seek().
 *
 * @todo Flesh out these error codes, making them as explicit as possible.
 */
APREQ_DECLARE(apr_status_t) apreq_brigade_concat(apr_pool_t *pool,
                                                 const char *temp_dir,
                                                 apr_size_t brigade_limit,
                                                 apr_bucket_brigade *out,
                                                 apr_bucket_brigade *in);

/**
 * Determines the spool file used by the brigade. Returns NULL if the
 * brigade is not spooled in a file (does not use an APREQ_SPOOL
 * bucket).
 *
 * @param bb the bucket brigade
 * @return the spool file, or NULL.
 */
APREQ_DECLARE(apr_file_t *) apreq_brigade_spoolfile(apr_bucket_brigade *bb);

#ifdef __cplusplus
 }
#endif

#endif /* APREQ_UTIL_H */
