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