/* Copyright 2000-2004 The Apache Software Foundation
 *
 * Licensed 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.
 */

/*
 * This attempts to generate V1 UUIDs according to the Internet Draft
 * located at http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
 */
#include "apr.h"
#include "apr_uuid.h"
#include "apr_md5.h"
#include "apr_general.h"
#include "apr_portable.h"


#if APR_HAVE_UNISTD_H
#include <unistd.h>     /* for getpid, gethostname */
#endif
#if APR_HAVE_STDLIB_H
#include <stdlib.h>     /* for rand, srand */
#endif


#if APR_HAVE_STRING_H
#include <string.h>
#endif
#if APR_HAVE_STRINGS_H
#include <strings.h>
#endif
#if APR_HAVE_NETDB_H
#include <netdb.h>
#endif
#if APR_HAVE_SYS_TIME_H
#include <sys/time.h>   /* for gettimeofday */
#endif

#define NODE_LENGTH 6

static int uuid_state_seqnum;
static unsigned char uuid_state_node[NODE_LENGTH] = { 0 };


static void get_random_info(unsigned char node[NODE_LENGTH])
{
#if APR_HAS_RANDOM

    (void) apr_generate_random_bytes(node, NODE_LENGTH);

#else

    unsigned char seed[APR_MD5_DIGESTSIZE];
    apr_md5_ctx_t c;

    /* ### probably should revise some of this to be a bit more portable */

    /* Leach & Salz use Linux-specific struct sysinfo;
     * replace with pid/tid for portability (in the spirit of mod_unique_id) */
    struct {
	/* Add thread id here, if applicable, when we get to pthread or apr */
        pid_t pid;
#ifdef NETWARE
        apr_uint64_t t;
#else
        struct timeval t;
#endif
        char hostname[257];

    } r;

    apr_md5_init(&c);
#ifdef NETWARE
    r.pid = NXThreadGetId();
    NXGetTime(NX_SINCE_BOOT, NX_USECONDS, &(r.t));
#else
    r.pid = getpid();
    gettimeofday(&r.t, (struct timezone *)0);
#endif
    gethostname(r.hostname, 256);
    apr_md5_update(&c, (const unsigned char *)&r, sizeof(r));
    apr_md5_final(seed, &c);

    memcpy(node, seed, NODE_LENGTH);    /* use a subset of the seed bytes */
#endif
}

/* This implementation generates a random node ID instead of a
   system-dependent call to get IEEE node ID. This is also more secure:
   we aren't passing out our MAC address.
*/
static void get_pseudo_node_identifier(unsigned char *node)
{
    get_random_info(node);
    node[0] |= 0x01;                    /* this designates a random node ID */
}

static void get_system_time(apr_uint64_t *uuid_time)
{
    /* ### fix this call to be more portable? */
    *uuid_time = apr_time_now();

    /* Offset between UUID formatted times and Unix formatted times.
       UUID UTC base time is October 15, 1582.
       Unix base time is January 1, 1970.      */
    *uuid_time = (*uuid_time * 10) + APR_TIME_C(0x01B21DD213814000);
}

/* true_random -- generate a crypto-quality random number. */
static int true_random(void)
{
    apr_uint64_t time_now;

#if APR_HAS_RANDOM
    unsigned char buf[2];

    if (apr_generate_random_bytes(buf, 2) == APR_SUCCESS) {
        return (buf[0] << 8) | buf[1];
    }
#endif

    /* crap. this isn't crypto quality, but it will be Good Enough */

    get_system_time(&time_now);
    srand((unsigned int)(((time_now >> 32) ^ time_now) & 0xffffffff));

    return rand() & 0x0FFFF;
}

static void init_state(void)
{
    uuid_state_seqnum = true_random();
    get_pseudo_node_identifier(uuid_state_node);
}

static void get_current_time(apr_uint64_t *timestamp)
{
    /* ### this needs to be made thread-safe! */

    apr_time_t time_now;
    static apr_interval_time_t time_last = 0;
    static apr_interval_time_t fudge = 0;

    time_now = apr_time_now();
        
    /* if clock reading changed since last UUID generated... */
    if (time_last != time_now) {
        /* The clock reading has changed since the last UUID was generated.
           Reset the fudge factor. if we are generating them too fast, then
           the fudge may need to be reset to something greater than zero. */
        if (time_last + fudge > time_now)
            fudge = time_last + fudge - time_now + 1;
        else
            fudge = 0;
        time_last = time_now;
    }
    else {
        /* We generated two really fast. Bump the fudge factor. */
        ++fudge;
    }

    *timestamp = time_now + fudge;
}

APU_DECLARE(void) apr_uuid_get(apr_uuid_t *uuid)
{
    apr_uint64_t timestamp;
    unsigned char *d = uuid->data;

#if APR_HAS_OS_UUID
    if (apr_os_uuid_get(d) == APR_SUCCESS) {
        return;
    }
#endif /* !APR_HAS_OS_UUID */

    if (!uuid_state_node[0])
        init_state();

    get_current_time(&timestamp);

    d[0] = (unsigned char)timestamp;
    d[1] = (unsigned char)(timestamp >> 8);
    d[2] = (unsigned char)(timestamp >> 16);
    d[3] = (unsigned char)(timestamp >> 24);
    d[4] = (unsigned char)(timestamp >> 32);
    d[5] = (unsigned char)(timestamp >> 40);
    d[6] = (unsigned char)(timestamp >> 48);
    d[7] = (unsigned char)(((timestamp >> 56) & 0x0F) | 0x10);

    d[8] = (unsigned char)(((uuid_state_seqnum >> 8) & 0x3F) | 0x80);
    d[9] = (unsigned char)uuid_state_seqnum;

    memcpy(&d[10], uuid_state_node, NODE_LENGTH);
}
