/*

   nsjail - useful procedures
   -----------------------------------------

   Copyright 2016 Google Inc. All Rights Reserved.

   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.

*/

#include "util.h"

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <sstream>
#include <string>
#include <vector>

#include "logs.h"
#include "macros.h"

namespace util {

ssize_t readFromFd(int fd, void* buf, size_t len) {
	uint8_t* charbuf = (uint8_t*)buf;

	size_t readSz = 0;
	while (readSz < len) {
		ssize_t sz = TEMP_FAILURE_RETRY(read(fd, &charbuf[readSz], len - readSz));
		if (sz <= 0) {
			break;
		}
		readSz += sz;
	}
	return readSz;
}

ssize_t readFromFile(const char* fname, void* buf, size_t len) {
	int fd;
	TEMP_FAILURE_RETRY(fd = open(fname, O_RDONLY | O_CLOEXEC));
	if (fd == -1) {
		LOG_E("open('%s', O_RDONLY|O_CLOEXEC)", fname);
		return -1;
	}
	ssize_t ret = readFromFd(fd, buf, len);
	close(fd);
	return ret;
}

bool writeToFd(int fd, const void* buf, size_t len) {
	const uint8_t* charbuf = (const uint8_t*)buf;

	size_t writtenSz = 0;
	while (writtenSz < len) {
		ssize_t sz = TEMP_FAILURE_RETRY(write(fd, &charbuf[writtenSz], len - writtenSz));
		if (sz < 0) {
			return false;
		}
		writtenSz += sz;
	}
	return true;
}

bool writeBufToFile(const char* filename, const void* buf, size_t len, int open_flags) {
	int fd;
	TEMP_FAILURE_RETRY(fd = open(filename, open_flags, 0644));
	if (fd == -1) {
		PLOG_E("Couldn't open '%s' for writing", filename);
		return false;
	}

	if (!writeToFd(fd, buf, len)) {
		PLOG_E("Couldn't write '%zu' bytes to file '%s' (fd='%d')", len, filename, fd);
		close(fd);
		if (open_flags & O_CREAT) {
			unlink(filename);
		}
		return false;
	}

	LOG_D("Written '%zu' bytes to '%s'", len, filename);

	close(fd);
	return true;
}

bool createDirRecursively(const char* dir) {
	if (dir[0] != '/') {
		LOG_W("The directory path must start with '/': '%s' provided", dir);
		return false;
	}

	int prev_dir_fd = open("/", O_RDONLY | O_CLOEXEC);
	if (prev_dir_fd == -1) {
		PLOG_W("open('/', O_RDONLY | O_CLOEXEC)");
		return false;
	}

	char path[PATH_MAX];
	snprintf(path, sizeof(path), "%s", dir);
	char* curr = path;
	for (;;) {
		while (*curr == '/') {
			curr++;
		}

		char* next = strchr(curr, '/');
		if (next == NULL) {
			close(prev_dir_fd);
			return true;
		}
		*next = '\0';

		if (mkdirat(prev_dir_fd, curr, 0755) == -1 && errno != EEXIST) {
			PLOG_W("mkdir('%s', 0755)", curr);
			close(prev_dir_fd);
			return false;
		}

		int dir_fd = TEMP_FAILURE_RETRY(openat(prev_dir_fd, curr, O_DIRECTORY | O_CLOEXEC));
		if (dir_fd == -1) {
			PLOG_W("openat('%d', '%s', O_DIRECTORY | O_CLOEXEC)", prev_dir_fd, curr);
			close(prev_dir_fd);
			return false;
		}
		close(prev_dir_fd);
		prev_dir_fd = dir_fd;
		curr = next + 1;
	}
}

std::string* StrAppend(std::string* str, const char* format, ...) {
	char* strp;

	va_list args;
	va_start(args, format);
	int ret = vasprintf(&strp, format, args);
	va_end(args);

	if (ret == -1) {
		PLOG_E("Memory allocation failed during asprintf()");
		str->append(" [ERROR: mem_allocation_failed] ");
		return str;
	}

	str->append(strp, ret);
	free(strp);
	return str;
}

std::string StrPrintf(const char* format, ...) {
	char* strp;

	va_list args;
	va_start(args, format);
	int ret = vasprintf(&strp, format, args);
	va_end(args);

	if (ret == -1) {
		PLOG_E("Memory allocation failed during asprintf()");
		return "[ERROR: mem_allocation_failed]";
	}

	std::string str(strp, ret);
	free(strp);
	return str;
}

bool isANumber(const char* s) {
	for (size_t i = 0; s[i]; s++) {
		if (!isdigit(s[i]) && s[i] != 'x') {
			return false;
		}
	}
	return true;
}

static __thread pthread_once_t rndThreadOnce = PTHREAD_ONCE_INIT;
static __thread uint64_t rndX;

/* MMIX LCG PRNG */
static const uint64_t a = 6364136223846793005ULL;
static const uint64_t c = 1442695040888963407ULL;

static void rndInitThread(void) {
#if defined(__NR_getrandom)
	if (syscall(__NR_getrandom, &rndX, sizeof(rndX), 0) == sizeof(rndX)) {
		return;
	}
#endif /* defined(__NR_getrandom) */
	int fd = open("/dev/urandom", O_RDONLY | O_CLOEXEC);
	if (fd == -1) {
		PLOG_D(
		    "Couldn't open /dev/urandom for reading. Using gettimeofday "
		    "fall-back");
		struct timeval tv;
		gettimeofday(&tv, NULL);
		rndX = tv.tv_usec + ((uint64_t)tv.tv_sec << 32);
		return;
	}
	if (readFromFd(fd, (uint8_t*)&rndX, sizeof(rndX)) != sizeof(rndX)) {
		PLOG_F("Couldn't read '%zu' bytes from /dev/urandom", sizeof(rndX));
		close(fd);
	}
	close(fd);
}

uint64_t rnd64(void) {
	pthread_once(&rndThreadOnce, rndInitThread);
	rndX = a * rndX + c;
	return rndX;
}

const std::string sigName(int signo) {
	std::string res;

	struct {
		const int signo;
		const char* const name;
	} static const sigNames[] = {
	    NS_VALSTR_STRUCT(SIGINT),
	    NS_VALSTR_STRUCT(SIGILL),
	    NS_VALSTR_STRUCT(SIGABRT),
	    NS_VALSTR_STRUCT(SIGFPE),
	    NS_VALSTR_STRUCT(SIGSEGV),
	    NS_VALSTR_STRUCT(SIGTERM),
	    NS_VALSTR_STRUCT(SIGHUP),
	    NS_VALSTR_STRUCT(SIGQUIT),
	    NS_VALSTR_STRUCT(SIGTRAP),
	    NS_VALSTR_STRUCT(SIGKILL),
	    NS_VALSTR_STRUCT(SIGBUS),
	    NS_VALSTR_STRUCT(SIGSYS),
	    NS_VALSTR_STRUCT(SIGPIPE),
	    NS_VALSTR_STRUCT(SIGALRM),
	    NS_VALSTR_STRUCT(SIGURG),
	    NS_VALSTR_STRUCT(SIGSTOP),
	    NS_VALSTR_STRUCT(SIGTSTP),
	    NS_VALSTR_STRUCT(SIGCONT),
	    NS_VALSTR_STRUCT(SIGCHLD),
	    NS_VALSTR_STRUCT(SIGTTIN),
	    NS_VALSTR_STRUCT(SIGTTOU),
	    NS_VALSTR_STRUCT(SIGPOLL),
	    NS_VALSTR_STRUCT(SIGXCPU),
	    NS_VALSTR_STRUCT(SIGXFSZ),
	    NS_VALSTR_STRUCT(SIGVTALRM),
	    NS_VALSTR_STRUCT(SIGPROF),
	    NS_VALSTR_STRUCT(SIGUSR1),
	    NS_VALSTR_STRUCT(SIGUSR2),
	    NS_VALSTR_STRUCT(SIGWINCH),
	};

	for (const auto& i : sigNames) {
		if (signo == i.signo) {
			res.append(i.name);
			return res;
		}
	}

	if (signo > SIGRTMIN) {
		res.append("SIG");
		res.append(std::to_string(signo));
		res.append("-RTMIN+");
		res.append(std::to_string(signo - SIGRTMIN));
		return res;
	}

	res.append("SIGUNKNOWN(");
	res.append(std::to_string(signo));
	res.append(")");
	return res;
}

const std::string timeToStr(time_t t) {
	char timestr[128];
	struct tm utctime;
	localtime_r(&t, &utctime);
	if (strftime(timestr, sizeof(timestr) - 1, "%FT%T%z", &utctime) == 0) {
		return "[Time conv error]";
	}
	return timestr;
}

std::vector<std::string> strSplit(const std::string str, char delim) {
	std::vector<std::string> vec;
	std::istringstream stream(str);
	for (std::string word; std::getline(stream, word, delim);) {
		vec.push_back(word);
	}
	return vec;
}

}  // namespace util
