/* 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 "apu.h"
#include "apr_private.h"
#include "apr_lib.h"
#include "apr_strings.h"
#include "apr_portable.h"
#include "apr_xlate.h"

/* If no implementation is available, don't generate code here since
 * apr_xlate.h emitted macros which return APR_ENOTIMPL.
 */

#if APR_HAS_XLATE

#ifdef HAVE_STDDEF_H
#include <stddef.h> /* for NULL */
#endif
#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_ICONV_H
#include <iconv.h>
#endif

#if defined(APU_ICONV_INBUF_CONST)
#define ICONV_INBUF_TYPE const char **
#else
#define ICONV_INBUF_TYPE char **
#endif

#ifndef min
#define min(x,y) ((x) <= (y) ? (x) : (y))
#endif

struct apr_xlate_t {
    apr_pool_t *pool;
    char *frompage;
    char *topage;
    char *sbcs_table;
#if APU_HAVE_ICONV
    iconv_t ich;
#endif
};


static const char *handle_special_names(const char *page, apr_pool_t *pool)
{
    if (page == APR_DEFAULT_CHARSET) {
        return apr_os_default_encoding(pool);
    }
    else if (page == APR_LOCALE_CHARSET) {
        return apr_os_locale_encoding(pool);
    }
#ifdef __MVS__
    else if (!strcasecmp(page, "ISO-8859-1")) {
       	return "ISO8859-1"; /* z/OS ASCII name has no dash after ISO */
    }
#endif
    else {
        return page;
    }
}

static apr_status_t apr_xlate_cleanup(void *convset)
{
    apr_xlate_t *old = convset;

#if APU_HAVE_ICONV
    if (old->ich != (iconv_t)-1) {
        if (iconv_close(old->ich)) {
            int rv = errno;

            /* Sometimes, iconv is not good about setting errno. */
            return rv ? rv : APR_EINVAL;
        }
    }
#endif

    return APR_SUCCESS;
}

#if APU_HAVE_ICONV
static void check_sbcs(apr_xlate_t *convset)
{
    char inbuf[256], outbuf[256];
    char *inbufptr = inbuf;
    char *outbufptr = outbuf;
    apr_size_t inbytes_left, outbytes_left;
    int i;
    apr_size_t translated;

    for (i = 0; i < sizeof(inbuf); i++) {
        inbuf[i] = i;
    }

    inbytes_left = outbytes_left = sizeof(inbuf);
    translated = iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                       &inbytes_left, &outbufptr, &outbytes_left);

    if (translated != (apr_size_t)-1
        && inbytes_left == 0
        && outbytes_left == 0) {
        /* hurray... this is simple translation; save the table,
         * close the iconv descriptor
         */

        convset->sbcs_table = apr_pmemdup(convset->pool, outbuf, sizeof(outbuf));

        iconv_close(convset->ich);
        convset->ich = (iconv_t)-1;

        /* TODO: add the table to the cache */
    }
    else {
        /* reset the iconv descriptor, since it's now in an undefined
         * state. */
        iconv_close(convset->ich);
        convset->ich = iconv_open(convset->topage, convset->frompage);
    }
}
#elif APU_HAVE_APR_ICONV
static void check_sbcs(apr_xlate_t *convset)
{
    char inbuf[256], outbuf[256];
    char *inbufptr = inbuf;
    char *outbufptr = outbuf;
    apr_size_t inbytes_left, outbytes_left;
    int i;
    apr_size_t translated;
    apr_status_t rv;

    for (i = 0; i < sizeof(inbuf); i++) {
        inbuf[i] = i;
    }

    inbytes_left = outbytes_left = sizeof(inbuf);
    rv = apr_iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                   &inbytes_left, &outbufptr, &outbytes_left,
                   &translated);

    if ((rv == APR_SUCCESS)
        && (translated != (apr_size_t)-1)
        && inbytes_left == 0
        && outbytes_left == 0) {
        /* hurray... this is simple translation; save the table,
         * close the iconv descriptor
         */

        convset->sbcs_table = apr_palloc(convset->pool, sizeof(outbuf));
        memcpy(convset->sbcs_table, outbuf, sizeof(outbuf));
        apr_iconv_close(convset->ich, convset->pool);
        convset->ich = (apr_iconv_t)-1;

        /* TODO: add the table to the cache */
    }
    else {
        /* reset the iconv descriptor, since it's now in an undefined
         * state. */
        apr_iconv_close(convset->ich, convset->pool);
        rv = apr_iconv_open(convset->topage, convset->frompage, 
                            convset->pool, &convset->ich);
    }
}
#endif /* APU_HAVE_APR_ICONV */

static void make_identity_table(apr_xlate_t *convset)
{
  int i;

  convset->sbcs_table = apr_palloc(convset->pool, 256);
  for (i = 0; i < 256; i++)
      convset->sbcs_table[i] = i;
}

APR_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset,
                                         const char *topage,
                                         const char *frompage,
                                         apr_pool_t *pool)
{
    apr_status_t rv;
    apr_xlate_t *new;
    int found = 0;

    *convset = NULL;

    topage = handle_special_names(topage, pool);
    frompage = handle_special_names(frompage, pool);

    new = (apr_xlate_t *)apr_pcalloc(pool, sizeof(apr_xlate_t));
    if (!new) {
        return APR_ENOMEM;
    }

    new->pool = pool;
    new->topage = apr_pstrdup(pool, topage);
    new->frompage = apr_pstrdup(pool, frompage);
    if (!new->topage || !new->frompage) {
        return APR_ENOMEM;
    }

#ifdef TODO
    /* search cache of codepage pairs; we may be able to avoid the
     * expensive iconv_open()
     */

    set found to non-zero if found in the cache
#endif

    if ((! found) && (strcmp(topage, frompage) == 0)) {
        /* to and from are the same */
        found = 1;
        make_identity_table(new);
    }

#if APU_HAVE_APR_ICONV
    if (!found) {
        rv = apr_iconv_open(topage, frompage, pool, &new->ich);
        if (rv != APR_SUCCESS) {
            return rv;
        }
        found = 1;
        check_sbcs(new);
    } else
        new->ich = (apr_iconv_t)-1;

#elif APU_HAVE_ICONV
    if (!found) {
        new->ich = iconv_open(topage, frompage);
        if (new->ich == (iconv_t)-1) {
            int rv = errno;
            /* Sometimes, iconv is not good about setting errno. */
            return rv ? rv : APR_EINVAL;
        }
        found = 1;
        check_sbcs(new);
    } else
        new->ich = (iconv_t)-1;
#endif /* APU_HAVE_ICONV */

    if (found) {
        *convset = new;
        apr_pool_cleanup_register(pool, (void *)new, apr_xlate_cleanup,
                            apr_pool_cleanup_null);
        rv = APR_SUCCESS;
    }
    else {
        rv = APR_EINVAL; /* iconv() would return EINVAL if it
                                couldn't handle the pair */
    }

    return rv;
}

APR_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff)
{
    *onoff = convset->sbcs_table != NULL;
    return APR_SUCCESS;
}

APR_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset,
                                                const char *inbuf,
                                                apr_size_t *inbytes_left,
                                                char *outbuf,
                                                apr_size_t *outbytes_left)
{
    apr_status_t status = APR_SUCCESS;

#if APU_HAVE_ICONV
    if (convset->ich != (iconv_t)-1) {
        const char *inbufptr = inbuf;
        char *outbufptr = outbuf;
        apr_size_t translated;
        translated = iconv(convset->ich, (ICONV_INBUF_TYPE)&inbufptr,
                           inbytes_left, &outbufptr, outbytes_left);

        /* If everything went fine but we ran out of buffer, don't
         * report it as an error.  Caller needs to look at the two
         * bytes-left values anyway.
         *
         * There are three expected cases where rc is -1.  In each of
         * these cases, *inbytes_left != 0.
         * a) the non-error condition where we ran out of output
         *    buffer
         * b) the non-error condition where we ran out of input (i.e.,
         *    the last input character is incomplete)
         * c) the error condition where the input is invalid
         */
        if (translated == (apr_size_t)-1) {
            int rv = errno;
            switch (rv) {

            case E2BIG:  /* out of space on output */
                status = 0; /* change table lookup code below if you
                               make this an error */
                break;

            case EINVAL: /* input character not complete (yet) */
                status = APR_INCOMPLETE;
                break;

            case EILSEQ: /* bad input byte */
                status = APR_EINVAL;
                break;

             /* Sometimes, iconv is not good about setting errno. */
            case 0:
                status = APR_INCOMPLETE;
                break;

            default:
                status = rv;
                break;
            }
        }
    }
    else
#endif

    if (inbuf) {
        apr_size_t to_convert = min(*inbytes_left, *outbytes_left);
        apr_size_t converted = to_convert;
        char *table = convset->sbcs_table;

        while (to_convert) {
            *outbuf = table[(unsigned char)*inbuf];
            ++outbuf;
            ++inbuf;
            --to_convert;
        }
        *inbytes_left -= converted;
        *outbytes_left -= converted;
    }

    return status;
}

APR_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset,
                                             unsigned char inchar)
{
    if (convset->sbcs_table) {
        return convset->sbcs_table[inchar];
    }
    else {
        return -1;
    }
}

APR_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset)
{
    return apr_pool_cleanup_run(convset->pool, convset, apr_xlate_cleanup);
}

#else /* !APR_HAS_XLATE */

APR_DECLARE(apr_status_t) apr_xlate_open(apr_xlate_t **convset,
                                         const char *topage,
                                         const char *frompage,
                                         apr_pool_t *pool)
{
    return APR_ENOTIMPL;
}

APR_DECLARE(apr_status_t) apr_xlate_sb_get(apr_xlate_t *convset, int *onoff)
{
    return APR_ENOTIMPL;
}

APR_DECLARE(apr_int32_t) apr_xlate_conv_byte(apr_xlate_t *convset,
                                             unsigned char inchar)
{
    return (-1);
}

APR_DECLARE(apr_status_t) apr_xlate_conv_buffer(apr_xlate_t *convset,
                                                const char *inbuf,
                                                apr_size_t *inbytes_left,
                                                char *outbuf,
                                                apr_size_t *outbytes_left)
{
    return APR_ENOTIMPL;
}

APR_DECLARE(apr_status_t) apr_xlate_close(apr_xlate_t *convset)
{
    return APR_ENOTIMPL;
}

#endif /* APR_HAS_XLATE */
