/*
 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
 *
 * %Begin-Header%
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, and the entire permission notice in its entirety,
 *    including the disclaimer of warranties.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
 * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * %End-Header%
 */

#include "uuid.h"

#include <stdint.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

#if TARGET_OS_MAC
#include <sys/socket.h>
#include <sys/time.h>

#include <mach/mach_time.h>

#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>

static inline void nanotime(struct timespec *tv) {
    uint64_t now = mach_absolute_time();
    tv->tv_sec = now / 1000000000;
    tv->tv_nsec = now - (tv->tv_sec * 1000000000);
}

#elif TARGET_OS_LINUX
#include <time.h>

static inline void nanotime(struct timespec *tv) {
	clock_gettime(CLOCK_MONOTONIC, tv);
}

#endif

static inline void read_random(void *buffer, u_int numBytes) {
    int fd = open("/dev/urandom", O_RDONLY);
    read(fd, buffer, numBytes);
    close(fd);
}


UUID_DEFINE(UUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

static void
read_node(uint8_t *node)
{
#if NETWORKING
	struct ifnet *ifp;
	struct ifaddr *ifa;
	struct sockaddr_dl *sdl;

	ifnet_head_lock_shared();
	TAILQ_FOREACH(ifp, &ifnet_head, if_link) {
		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
			sdl = (struct sockaddr_dl *)ifa->ifa_addr;
			if (sdl && sdl->sdl_family == AF_LINK && sdl->sdl_type == IFT_ETHER) {
				memcpy(node, LLADDR(sdl), 6);
				ifnet_head_done();
				return;
			}
		}
	}
	ifnet_head_done();
#endif /* NETWORKING */

	read_random(node, 6);
	node[0] |= 0x01;
}

static uint64_t
read_time(void)
{
	struct timespec tv;

	nanotime(&tv);

	return (tv.tv_sec * 10000000ULL) + (tv.tv_nsec / 100ULL) + 0x01B21DD213814000ULL;
}

void
uuid_clear(uuid_t uu)
{
	memset(uu, 0, sizeof(uuid_t));
}

int
uuid_compare(const uuid_t uu1, const uuid_t uu2)
{
	return memcmp(uu1, uu2, sizeof(uuid_t));
}

void
uuid_copy(uuid_t dst, const uuid_t src)
{
	memcpy(dst, src, sizeof(uuid_t));
}

void
uuid_generate_random(uuid_t out)
{
	read_random(out, sizeof(uuid_t));

	out[6] = (out[6] & 0x0F) | 0x40;
	out[8] = (out[8] & 0x3F) | 0x80;
}

void
uuid_generate_time(uuid_t out)
{
	uint64_t time;

	read_node(&out[10]);
	read_random(&out[8], 2);

	time = read_time();
	out[0] = (uint8_t)(time >> 24);
	out[1] = (uint8_t)(time >> 16);
	out[2] = (uint8_t)(time >> 8);
	out[3] = (uint8_t)time;
	out[4] = (uint8_t)(time >> 40);
	out[5] = (uint8_t)(time >> 32);
	out[6] = (uint8_t)(time >> 56);
	out[7] = (uint8_t)(time >> 48);
 
	out[6] = (out[6] & 0x0F) | 0x10;
	out[8] = (out[8] & 0x3F) | 0x80;
}

void
uuid_generate(uuid_t out)
{
	uuid_generate_random(out);
}

int
uuid_is_null(const uuid_t uu)
{
	return !memcmp(uu, UUID_NULL, sizeof(uuid_t));
}

int
uuid_parse(const uuid_string_t in, uuid_t uu)
{
	int n = 0;

	sscanf(in,
		"%2hhx%2hhx%2hhx%2hhx-"
		"%2hhx%2hhx-"
		"%2hhx%2hhx-"
		"%2hhx%2hhx-"
		"%2hhx%2hhx%2hhx%2hhx%2hhx%2hhx%n",
		&uu[0], &uu[1], &uu[2], &uu[3],
		&uu[4], &uu[5],
		&uu[6], &uu[7],
		&uu[8], &uu[9],
		&uu[10], &uu[11], &uu[12], &uu[13], &uu[14], &uu[15], &n);

	return (n != 36 || in[n] != '\0' ? -1 : 0);
}

void
uuid_unparse_lower(const uuid_t uu, uuid_string_t out)
{
	snprintf(out,
		sizeof(uuid_string_t),
		"%02x%02x%02x%02x-"
		"%02x%02x-"
		"%02x%02x-"
		"%02x%02x-"
		"%02x%02x%02x%02x%02x%02x",
		uu[0], uu[1], uu[2], uu[3],
		uu[4], uu[5],
		uu[6], uu[7],
		uu[8], uu[9],
		uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
}

void
uuid_unparse_upper(const uuid_t uu, uuid_string_t out)
{
	snprintf(out,
		sizeof(uuid_string_t),
		"%02X%02X%02X%02X-"
		"%02X%02X-"
		"%02X%02X-"
		"%02X%02X-"
		"%02X%02X%02X%02X%02X%02X",
		uu[0], uu[1], uu[2], uu[3],
		uu[4], uu[5],
		uu[6], uu[7],
		uu[8], uu[9],
		uu[10], uu[11], uu[12], uu[13], uu[14], uu[15]);
}

void
uuid_unparse(const uuid_t uu, uuid_string_t out)
{
	uuid_unparse_upper(uu, out);
}