/*
 * Copyright (C) 2012-2013  ProFUSION embedded systems
 *
 * This program 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 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
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include <assert.h>
#include <dirent.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <shared/util.h>

#include "testsuite.h"

static void *nextlib;
static const char *rootpath;
static size_t rootpathlen;

static inline bool need_trap(const char *path)
{
	return path != NULL && path[0] == '/'
		&& !strstartswith(path, ABS_TOP_BUILDDIR);
}

static const char *trap_path(const char *path, char buf[PATH_MAX * 2])
{
	size_t len;

	if (!need_trap(path))
		return path;

	len = strlen(path);

	if (len + rootpathlen > PATH_MAX * 2) {
		errno = ENAMETOOLONG;
		return NULL;
	}

	memcpy(buf, rootpath, rootpathlen);
	strcpy(buf + rootpathlen, path);
	return buf;
}

static bool get_rootpath(const char *f)
{
	if (rootpath != NULL)
		return true;

	rootpath = getenv(S_TC_ROOTFS);
	if (rootpath == NULL) {
		ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS);
		errno = ENOENT;
		return false;
	}

	rootpathlen = strlen(rootpath);

	return true;
}

static void *get_libc_func(const char *f)
{
	void *fp;

	if (nextlib == NULL) {
#ifdef RTLD_NEXT
		nextlib = RTLD_NEXT;
#else
		nextlib = dlopen("libc.so.6", RTLD_LAZY);
#endif
	}

	fp = dlsym(nextlib, f);
	assert(fp);

	return fp;
}

/* wrapper template for a function with one "const char* path" argument */
#define WRAP_1ARG(rettype, failret, name) \
TS_EXPORT rettype name(const char *path) \
{ \
	const char *p;				\
	char buf[PATH_MAX * 2];                 \
	static rettype (*_fn)(const char*);	\
						\
	if (!get_rootpath(__func__))		\
		return failret;			\
	_fn = get_libc_func(#name);		\
	p = trap_path(path, buf);		\
	if (p == NULL)				\
		return failret;			\
	return (*_fn)(p);			\
}

/* wrapper template for a function with "const char* path" and another argument */
#define WRAP_2ARGS(rettype, failret, name, arg2t)	\
TS_EXPORT rettype name(const char *path, arg2t arg2)	\
{ \
	const char *p;					\
	char buf[PATH_MAX * 2];				\
	static rettype (*_fn)(const char*, arg2t arg2);	\
							\
	if (!get_rootpath(__func__))			\
		return failret;				\
	_fn = get_libc_func(#name);			\
	p = trap_path(path, buf);			\
	if (p == NULL)					\
		return failret;				\
	return (*_fn)(p, arg2);				\
}

/* wrapper template for open family */
#define WRAP_OPEN(suffix)					\
TS_EXPORT int open ## suffix (const char *path, int flags, ...)	\
{ \
	const char *p;						\
	char buf[PATH_MAX * 2];					\
	static int (*_fn)(const char *path, int flags, ...);	\
								\
	if (!get_rootpath(__func__))				\
		return -1;					\
	_fn = get_libc_func("open" #suffix);			\
	p = trap_path(path, buf);				\
	if (p == NULL)						\
		return -1;					\
								\
	if (flags & O_CREAT) {					\
		mode_t mode;					\
		va_list ap;					\
								\
		va_start(ap, flags);				\
		mode = va_arg(ap, mode_t);			\
		va_end(ap);					\
		return _fn(p, flags, mode);			\
	}							\
								\
	return _fn(p, flags);					\
}

/* wrapper template for __xstat family */
#define WRAP_VERSTAT(prefix, suffix)			    \
TS_EXPORT int prefix ## stat ## suffix (int ver,	    \
			      const char *path,		    \
	                      struct stat ## suffix *st)    \
{ \
	const char *p;					    \
	char buf[PATH_MAX * 2];				    \
	static int (*_fn)(int ver, const char *path,	    \
		          struct stat ## suffix *);	    \
	_fn = get_libc_func(#prefix "stat" #suffix);	    \
							    \
	if (!get_rootpath(__func__))			    \
		return -1;				    \
	p = trap_path(path, buf);			    \
	if (p == NULL)					    \
		return -1;				    \
							    \
	return _fn(ver, p, st);				    \
}

WRAP_1ARG(DIR*, NULL, opendir);

WRAP_2ARGS(FILE*, NULL, fopen, const char*);
WRAP_2ARGS(int, -1, mkdir, mode_t);
WRAP_2ARGS(int, -1, access, int);
WRAP_2ARGS(int, -1, stat, struct stat*);
WRAP_2ARGS(int, -1, lstat, struct stat*);
#ifndef _FILE_OFFSET_BITS
WRAP_2ARGS(int, -1, stat64, struct stat64*);
WRAP_2ARGS(int, -1, lstat64, struct stat64*);
WRAP_OPEN(64);
#endif

WRAP_OPEN();

#ifdef HAVE___XSTAT
WRAP_VERSTAT(__x,);
WRAP_VERSTAT(__lx,);
#ifndef _FILE_OFFSET_BITS
WRAP_VERSTAT(__x,64);
WRAP_VERSTAT(__lx,64);
#endif
#endif
