/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


#include "os.h"


uint8_t osFileExists(char *filename) {
	FILE *f = fopen(filename, "rb");
	if (f) {
		fclose(f);
		return 1;
	}
	return 0;
}


char *osLastPathComponentGet(char *pathname) {
	static char *start;
	int32_t      x;

	start = pathname;

	// Scan through name and find the last path separator
	for (x=0; x<(int32_t)strlen(pathname); x++) {
		if (pathname[x] == '\\' || pathname[x] == '/') {
			start = &pathname[x + 1];
		}
	}

	return start;
}


char *osLastPathComponentGetUpTo(char *pathname) {
	static char *copy = NULL;
	uint8_t      dumb = 0;  // Using (copy == NULL) below didn't work after optimizations, so ente
	int32_t      x;

	x = (int32_t)(strlen(pathname) - strlen(osLastPathComponentGet(pathname))) - 1;
	if (x < 0) x = 0;
	if (dumb) {
		free(copy);
		copy = NULL;
	} else {
		dumb = 1;
	}
	copy = strdup(pathname);
	copy[x] = 0;
	osPathSeparatorsFix(&copy, 1);

	return copy;
}


int8_t osMkDir(char *dir) {
	return mkdir(dir, 0777);
}


uint8_t osMkDirP(char *dir) {
	char         tmp[OS_PATH_MAX];
	char        *p   = NULL;
	struct stat  sb;
	size_t       len;

	// Make copy of dir.
	len = strnlen(dir, OS_PATH_MAX);
	if (len == 0 || len == OS_PATH_MAX) {
		return FAIL;
	}
	memcpy(tmp, dir, len);
	tmp[len] = '\0';

	// Remove trailing slash.
	if (tmp[len - 1] == OS_PATH_SLASH) {
		tmp[len - 1] = '\0';
	}

	// Does it already exist?
	if (stat(tmp, &sb) == 0) {
		if (S_ISDIR (sb.st_mode)) {
			return SUCCESS;
		}
	}

	// Recursive mkdir.
	for (p = tmp + 1; *p; p++) {
		if (*p == OS_PATH_SLASH) {
			*p = 0;
			if (stat(tmp, &sb) != 0) {
				// Does not exist - create it.
				if (osMkDir(tmp) < 0) {
					return FAIL;
				}
			} else {
				if (!S_ISDIR(sb.st_mode)) {
					// Not a directory
					return FAIL;
				}
			}
			*p = OS_PATH_SLASH;
		}
	}
	// Check path
	if (stat(tmp, &sb) != 0) {
		// Does not exist - create it.
		if (osMkDir(tmp) < 0) {
			return FAIL;
		}
	} else {
		if (!S_ISDIR(sb.st_mode)) {
			// Not a directory
			return FAIL;
		}
	}

	return SUCCESS;
}


void osPathSeparatorsFix(char **path, uint8_t slash) {

	int32_t  i    =  0;
	int32_t  j    =  0;
	char    *work = *path;
	char    *temp =  NULL;

	// Flip path separators to whatever our OS wants & remove repeated separators.
	while (work[i] != 0) {
		// Correct separator
		if (work[i] == '\\' || work[i] == '/') {
			// Was the prior character a seprator?
			if (j == 0) {
				work[j++] = OS_PATH_SLASH;
			} else {
				if (work[j - 1] != OS_PATH_SLASH) {
					// No, accept it.
					work[j++] = OS_PATH_SLASH;
				}
		}
		} else {
			work[j++] = work[i];
		}
		i++;
	}
	work[j] = 0;

	if (slash) {
		// Does this string end with a path separator?
		if (work[strlen(work) - 1] != OS_PATH_SLASH) {
			// No - append one.
			temp = strdup(work);
			free(work);
			work = malloc(sizeof(char) * (strlen(temp) + 2));
			strcpy(work, temp);
			work[strlen(temp)] = OS_PATH_SLASH;
			work[strlen(temp) + 1] = 0;
			free(temp);
		}
	}

	*path = work;
}


void osShutdown(void) {
#ifdef __linux__
	linuxOsShutdown();
#endif
}


void osStartup(void) {
#ifdef __linux__
	linuxOsStartup();
#endif

	srand(rawclock());
}
