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

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

    time_now = apr_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_uint64_t time_now;
    static apr_uint64_t time_last = 0;
    static apr_uint64_t fudge = 0;

    get_system_time(&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;
}

APR_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);

    /* time_low, uint32 */
    d[3] = (unsigned char)timestamp;
    d[2] = (unsigned char)(timestamp >> 8);
    d[1] = (unsigned char)(timestamp >> 16);
    d[0] = (unsigned char)(timestamp >> 24);
    /* time_mid, uint16 */
    d[5] = (unsigned char)(timestamp >> 32);
    d[4] = (unsigned char)(timestamp >> 40);
    /* time_hi_and_version, uint16 */
    d[7] = (unsigned char)(timestamp >> 48);
    d[6] = (unsigned char)(((timestamp >> 56) & 0x0F) | 0x10);
    /* clock_seq_hi_and_reserved, uint8 */
    d[8] = (unsigned char)(((uuid_state_seqnum >> 8) & 0x3F) | 0x80);
    /* clock_seq_low, uint8 */
    d[9] = (unsigned char)uuid_state_seqnum;
    /* node, byte[6] */
    memcpy(&d[10], uuid_state_node, NODE_LENGTH);
}
