/*
 * DNS support
 *
 * Copyright (C) 2006 Matthew Kehrer
 * Copyright (C) 2006 Hans Leidekker
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#include <stdarg.h>
#include <sys/types.h>

#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_NAMESER_H
# include <arpa/nameser.h>
#endif
#ifdef HAVE_RESOLV_H
# include <resolv.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "windns.h"

#include "dnsapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);

/******************************************************************************
 * DnsNameCompare_A               [DNSAPI.@]
 *
 */
BOOL WINAPI DnsNameCompare_A( LPSTR name1, LPSTR name2 )
{
    BOOL ret;
    LPWSTR name1W, name2W;

    TRACE( "(%s,%s)\n", debugstr_a(name1), debugstr_a(name2) );

    name1W = dns_strdup_aw( name1 );
    name2W = dns_strdup_aw( name2 );

    ret = DnsNameCompare_W( name1W, name2W );

    dns_free( name1W );
    dns_free( name2W );

    return ret;
}

/******************************************************************************
 * DnsNameCompare_W               [DNSAPI.@]
 *
 */
BOOL WINAPI DnsNameCompare_W( LPWSTR name1, LPWSTR name2 )
{
    WCHAR *p, *q;

    TRACE( "(%s,%s)\n", debugstr_w(name1), debugstr_w(name2) );

    if (!name1 && !name2) return TRUE;
    if (!name1 || !name2) return FALSE;
 
    p = name1 + lstrlenW( name1 ) - 1;
    q = name2 + lstrlenW( name2 ) - 1;

    while (*p == '.' && p >= name1) p--;
    while (*q == '.' && q >= name2) q--;

    if (p - name1 != q - name2) return FALSE;

    while (name1 <= p)
    {
        if (toupperW( *name1 ) != toupperW( *name2 ))
            return FALSE;

        name1++;
        name2++;
    }
    return TRUE;
}

/******************************************************************************
 * DnsValidateName_A              [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsValidateName_A( LPCSTR name, DNS_NAME_FORMAT format )
{
    LPWSTR nameW;
    DNS_STATUS ret;

    TRACE( "(%s, %d)\n", debugstr_a(name), format );

    nameW = dns_strdup_aw( name );
    ret = DnsValidateName_W( nameW, format );

    dns_free( nameW );
    return ret;
}

/******************************************************************************
 * DnsValidateName_UTF8           [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsValidateName_UTF8( LPCSTR name, DNS_NAME_FORMAT format )
{
    LPWSTR nameW;
    DNS_STATUS ret;

    TRACE( "(%s, %d)\n", debugstr_a(name), format );

    nameW = dns_strdup_uw( name );
    ret = DnsValidateName_W( nameW, format );

    dns_free( nameW );
    return ret;
}

#define HAS_EXTENDED        0x0001
#define HAS_NUMERIC         0x0002
#define HAS_NON_NUMERIC     0x0004
#define HAS_DOT             0x0008
#define HAS_DOT_DOT         0x0010
#define HAS_SPACE           0x0020
#define HAS_INVALID         0x0040
#define HAS_ASTERISK        0x0080
#define HAS_UNDERSCORE      0x0100
#define HAS_LONG_LABEL      0x0200

/******************************************************************************
 * DnsValidateName_W              [DNSAPI.@]
 *
 */
DNS_STATUS WINAPI DnsValidateName_W( LPCWSTR name, DNS_NAME_FORMAT format )
{
    const WCHAR *p;
    unsigned int i, j, state = 0;
    static const WCHAR invalid[] = {
        '{','|','}','~','[','\\',']','^','\'',':',';','<','=','>',
        '?','@','!','\"','#','$','%','^','`','(',')','+','/',',',0 };

    TRACE( "(%s, %d)\n", debugstr_w(name), format );

    if (!name) return ERROR_INVALID_NAME;

    for (p = name, i = 0, j = 0; *p; p++, i++, j++)
    {
        if (*p == '.')
        {
            j = 0;
            state |= HAS_DOT;
            if (p[1] == '.') state |= HAS_DOT_DOT;
        }
        else if (*p < '0' || *p > '9') state |= HAS_NON_NUMERIC;
        else state |= HAS_NUMERIC;

        if (j > 62) state |= HAS_LONG_LABEL;

        if (strchrW( invalid, *p )) state |= HAS_INVALID;
        else if ((unsigned)*p > 127) state |= HAS_EXTENDED;
        else if (*p == ' ') state |= HAS_SPACE;
        else if (*p == '_') state |= HAS_UNDERSCORE;
        else if (*p == '*') state |= HAS_ASTERISK;
    }

    if (i == 0 || i > 255 ||
        (state & HAS_LONG_LABEL) ||
        (state & HAS_DOT_DOT) ||
        (name[0] == '.' && name[1])) return ERROR_INVALID_NAME;

    switch (format)
    {
    case DnsNameDomain:
    {
        if (!(state & HAS_NON_NUMERIC) && (state & HAS_NUMERIC))
            return DNS_ERROR_NUMERIC_NAME;
        if ((state & HAS_EXTENDED) || (state & HAS_UNDERSCORE))
            return DNS_ERROR_NON_RFC_NAME;
        if ((state & HAS_SPACE) ||
            (state & HAS_INVALID) ||
            (state & HAS_ASTERISK)) return DNS_ERROR_INVALID_NAME_CHAR;
        break;
    }
    case DnsNameDomainLabel:
    {
        if (state & HAS_DOT) return ERROR_INVALID_NAME;
        if ((state & HAS_EXTENDED) || (state & HAS_UNDERSCORE))
            return DNS_ERROR_NON_RFC_NAME;
        if ((state & HAS_SPACE) ||
            (state & HAS_INVALID) ||
            (state & HAS_ASTERISK)) return DNS_ERROR_INVALID_NAME_CHAR;
        break;
    }
    case DnsNameHostnameFull:
    {
        if (!(state & HAS_NON_NUMERIC) && (state & HAS_NUMERIC))
            return DNS_ERROR_NUMERIC_NAME;
        if ((state & HAS_EXTENDED) || (state & HAS_UNDERSCORE))
            return DNS_ERROR_NON_RFC_NAME;
        if ((state & HAS_SPACE) ||
            (state & HAS_INVALID) ||
            (state & HAS_ASTERISK)) return DNS_ERROR_INVALID_NAME_CHAR;
        break;
    }
    case DnsNameHostnameLabel:
    {
        if (state & HAS_DOT) return ERROR_INVALID_NAME;
        if (!(state & HAS_NON_NUMERIC) && (state & HAS_NUMERIC))
            return DNS_ERROR_NUMERIC_NAME;
        if ((state & HAS_EXTENDED) || (state & HAS_UNDERSCORE))
            return DNS_ERROR_NON_RFC_NAME;
        if ((state & HAS_SPACE) ||
            (state & HAS_INVALID) ||
            (state & HAS_ASTERISK)) return DNS_ERROR_INVALID_NAME_CHAR;
        break;
    }
    case DnsNameWildcard:
    {
        if (!(state & HAS_NON_NUMERIC) && (state & HAS_NUMERIC))
            return ERROR_INVALID_NAME;
        if (name[0] != '*') return ERROR_INVALID_NAME;
        if (name[1] && name[1] != '.')
            return DNS_ERROR_INVALID_NAME_CHAR;
        if ((state & HAS_EXTENDED) ||
            (state & HAS_SPACE) ||
            (state & HAS_INVALID)) return ERROR_INVALID_NAME;
        break;
    }
    case DnsNameSrvRecord:
    {
        if (!(state & HAS_NON_NUMERIC) && (state & HAS_NUMERIC))
            return ERROR_INVALID_NAME;
        if (name[0] != '_') return ERROR_INVALID_NAME;
        if ((state & HAS_UNDERSCORE) && !name[1])
            return DNS_ERROR_NON_RFC_NAME;
        if ((state & HAS_EXTENDED) ||
            (state & HAS_SPACE) ||
            (state & HAS_INVALID)) return ERROR_INVALID_NAME;
        break;
    }
    default:
        WARN( "unknown format: %d\n", format );
        break;
    }
    return ERROR_SUCCESS;
}
