/* $Id$ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjlib-util/errno.h>
#include <pjlib-util/types.h>
#include <pj/assert.h>
#include <pj/string.h>



/* PJLIB_UTIL's own error codes/messages 
 * MUST KEEP THIS ARRAY SORTED!!
 * Message must be limited to 64 chars!
 */
#if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0
static const struct 
{
    int code;
    const char *msg;
} err_str[] = 
{
    /* STUN errors */
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRESOLVE,	"Unable to resolve STUN server" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGTYPE,	"Unknown STUN message type" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGLEN,	"Invalid STUN message length" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRLEN,	"STUN attribute length error" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRTYPE,	"Invalid STUN attribute type" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNININDEX,	"Invalid STUN server/socket index" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOBINDRES,	"No STUN binding response in the message" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRECVERRATTR,	"Received STUN error attribute" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOMAP,	"No STUN mapped address attribute" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPOND,	"Received no response from STUN server" ),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNSYMMETRIC,	"Symetric NAT detected by STUN" ),

    /* XML errors */
    PJ_BUILD_ERR( PJLIB_UTIL_EINXML,		"Invalid XML message" ),

    /* DNS errors */
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSQRYTOOSMALL,	"DNS query packet buffer is too small"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINSIZE,	"Invalid DNS packet length"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINCLASS,	"Invalid DNS class"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNAMEPTR,	"Invalid DNS name pointer"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNSADDR,	"Invalid DNS nameserver address"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNONS,		"No nameserver is in DNS resolver"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOWORKINGNS,	"No working DNS nameserver"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOANSWERREC,	"No answer record in the DNS response"),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNSINANSWER,	"Invalid DNS answer"),

    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_FORMERR,	"DNS \"Format error\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_SERVFAIL,	"DNS \"Server failure\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXDOMAIN,	"DNS \"Name Error\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTIMPL,	"DNS \"Not Implemented\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_REFUSED,	"DNS \"Refused\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXDOMAIN,	"DNS \"The name exists\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXRRSET,	"DNS \"The RRset (name, type) exists\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXRRSET,	"DNS \"The RRset (name, type) does not exist\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTAUTH,	"DNS \"Not authorized\""),
    PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTZONE,	"DNS \"The zone specified is not a zone\""),

    /* STUN */
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTOOMANYATTR,	"Too many STUN attributes"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNUNKNOWNATTR,	"Unknown STUN attribute"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINADDRLEN,	"Invalid STUN socket address length"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNIPV6NOTSUPP,	"STUN IPv6 attribute not supported"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPONSE,	"Expecting STUN response message"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINVALIDID,	"STUN transaction ID mismatch"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOHANDLER,	"Unable to find STUN handler for the request"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINTPOS,	"Found non-FINGERPRINT attr. after MESSAGE-INTEGRITY"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNFINGERPOS,	"Found STUN attribute after FINGERPRINT"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOUSERNAME,	"Missing STUN USERNAME attribute"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINT,	"Missing/invalid STUN MESSAGE-INTEGRITY attribute"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNDUPATTR,	"Found duplicate STUN attribute"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOREALM,	"Missing STUN REALM attribute"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNONCE,	"Missing/stale STUN NONCE attribute value"),
    PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTSXFAILED,	"STUN transaction terminates with failure"),

    /* HTTP Client */
    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINURL,	"Invalid URL format"),
    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINPORT,	"Invalid URL port number"),
    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINCHDR,	"Incomplete response header received"),
    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINSBUF,	"Insufficient buffer"),
    PJ_BUILD_ERR( PJLIB_UTIL_EHTTPLOST,	        "Connection lost"),

    /* CLI */
    PJ_BUILD_ERR( PJ_CLI_EEXIT,	                "Exit current session"),
    PJ_BUILD_ERR( PJ_CLI_EMISSINGARG,	        "Missing argument"),
    PJ_BUILD_ERR( PJ_CLI_ETOOMANYARGS,	        "Too many arguments"),
    PJ_BUILD_ERR( PJ_CLI_EINVARG,	        "Invalid argument"),
    PJ_BUILD_ERR( PJ_CLI_EBADNAME,	        "Command name already exists"),
    PJ_BUILD_ERR( PJ_CLI_EBADID,	        "Command id already exists"),
    PJ_BUILD_ERR( PJ_CLI_EBADXML,	        "Invalid XML format"),
    PJ_BUILD_ERR( PJ_CLI_ETELNETLOST,	        "Connection lost"),
};
#endif	/* PJ_HAS_ERROR_STRING */


/*
 * pjlib_util_strerror()
 */
pj_str_t pjlib_util_strerror(pj_status_t statcode, 
			     char *buf, pj_size_t bufsize )
{
    pj_str_t errstr;

#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)

    if (statcode >= PJLIB_UTIL_ERRNO_START && 
	statcode < PJLIB_UTIL_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
    {
	/* Find the error in the table.
	 * Use binary search!
	 */
	int first = 0;
	int n = PJ_ARRAY_SIZE(err_str);

	while (n > 0) {
	    int half = n/2;
	    int mid = first + half;

	    if (err_str[mid].code < statcode) {
		first = mid+1;
		n -= (half+1);
	    } else if (err_str[mid].code > statcode) {
		n = half;
	    } else {
		first = mid;
		break;
	    }
	}


	if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
	    pj_str_t msg;
	    
	    msg.ptr = (char*)err_str[first].msg;
	    msg.slen = pj_ansi_strlen(err_str[first].msg);

	    errstr.ptr = buf;
	    pj_strncpy_with_null(&errstr, &msg, bufsize);
	    return errstr;

	} 
    }

#endif	/* PJ_HAS_ERROR_STRING */


    /* Error not found. */
    errstr.ptr = buf;
    errstr.slen = pj_ansi_snprintf(buf, bufsize, 
				   "Unknown pjlib-util error %d",
				   statcode);

    return errstr;
}


PJ_DEF(pj_status_t) pjlib_util_init(void)
{
    pj_status_t status;
    
    status = pj_register_strerror(PJLIB_UTIL_ERRNO_START, 
				  PJ_ERRNO_SPACE_SIZE, 
				  &pjlib_util_strerror);
    pj_assert(status == PJ_SUCCESS);

    return PJ_SUCCESS;
}
