/*
 * hostapd / Interface steering
 * Copyright (c) 2015 Google, Inc.
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include "common.h"
#include "common/defs.h"
#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "steering.h"

static int get_timestamp_filename(const struct ieee80211_mgmt *mgmt,
                                  logged_request_type type,
                                  steering_path_type path_type, char *buf,
                                  size_t len) {
  char *path = (path_type == STEERING_PATH ?
                steering_timestamp_path : request_logging_path);

	if (path == NULL) {
		return 0;
	}

	if (os_snprintf(buf, len, "%s/" COMPACT_MACSTR ".%d", path,
	                MAC2STR(mgmt->sa), type) < 0) {
		wpa_printf(MSG_ERROR, "os_snprintf couldn't format filename: %s",
		           strerror(errno));
		return 0;
	}

	return 1;
}

int write_timestamp_file(const struct ieee80211_mgmt *mgmt,
                         const struct hostapd_data *hapd,
                         logged_request_type type,
                         const struct os_reltime timestamp) {
	FILE *f;
	char filename[1024], tmp_filename[1024];
	int success = 0;

	if (!get_timestamp_filename(mgmt, type, LOGGING_PATH, filename,
	                            sizeof(filename))) {
		return 0;
	}

	/* Create a temporary filename to prevent multiple interfaces on the same band
	 * from touching each others' writes.
	 */
	if (os_snprintf(tmp_filename, sizeof(tmp_filename), "%s%s", filename,
	                os_strrchr(hapd->iface->config_fname, '.')) < 0) {
		wpa_printf(MSG_ERROR, "os_snprintf couldn't format temp filename: %s",
		           strerror(errno));
		return 0;
	}

	if ((f = fopen(tmp_filename, "w")) == NULL) {
		wpa_printf(MSG_ERROR, "fopen(%s) for write: %s", tmp_filename,
		           strerror(errno));
		return 0;
	}

	if (fprintf(f, "%d %d", timestamp.sec, timestamp.usec) < 0) {
		wpa_printf(MSG_ERROR, "fprintf to %s: %s", tmp_filename, strerror(errno));
	} else {
		success = 1;
	}

	if (fclose(f) == EOF) {
		wpa_printf(MSG_ERROR, "fclose(%s): %s", tmp_filename, strerror(errno));
		return 0;
	}

	if (rename(tmp_filename, filename) != 0) {
		wpa_printf(MSG_ERROR, "rename(%s, %s): %s", tmp_filename, filename,
		           strerror(errno));
		return 0;
	}

	return success;
}

int maybe_write_timestamp_file(const struct ieee80211_mgmt *mgmt,
                               const struct hostapd_data *hapd,
                               logged_request_type type) {
	struct os_reltime now, prev_logged_timestamp, new_timestamp;
	if (!request_logging_path) {
		return 0;
	}

	os_get_reltime(&now);
	if (garbage_collect_timestamp_files() == -1) {
		wpa_printf(MSG_ERROR,
		           "Garbage collecting steering timestamp files failed: %s",
		           strerror(errno));
		return 0;
	}
	if (!read_timestamp_file(mgmt, type, LOGGING_PATH, &prev_logged_timestamp) ||
	    os_reltime_expired(&now, &prev_logged_timestamp,
	                       BANDSTEERING_EXPIRATION_SECONDS)) {
		new_timestamp.sec = now.sec + BANDSTEERING_DELAY_SECONDS;
		new_timestamp.usec = now.usec;
		if (!write_timestamp_file(mgmt, hapd, type, new_timestamp)) {
			wpa_printf(MSG_ERROR, "Failed to write timestamp file.");
			return 0;
		} else {
			wpa_printf(MSG_INFO, "Set timestamp for " MACSTR " (type=%d)",
			           MAC2STR(mgmt->sa), type);
			return 1;
		}
	}
}

int read_timestamp_file(const struct ieee80211_mgmt *mgmt,
                        logged_request_type type,
                        steering_path_type path_type,
                        struct os_reltime *timestamp) {
	FILE *f;
	char filename[1024];
	int success = 0;
	struct stat st;
	os_time_t sec = 0, usec = 0;

	if (!get_timestamp_filename(mgmt, type, path_type, filename,
	                            sizeof(filename))) {
		return 0;
	}

	if (stat(filename, &st) == -1) {
		return 0;
	}

	f = fopen(filename, "r");
	if (f == NULL) {
		wpa_printf(MSG_ERROR, "open(%s) for read: %s", filename, strerror(errno));
		return 0;
	}

	if (fscanf(f, "%d %d", &timestamp->sec, &timestamp->usec) != 2) {
		wpa_printf(MSG_ERROR, "fscanf from %s: %s", filename, strerror(errno));
	} else {
		success = 1;
	}

	if (fclose(f) == EOF) {
		wpa_printf(MSG_ERROR, "fclose(%s): %s", filename, strerror(errno));
		return 0;
	}

	return success;
}

int file_ctime_lt(const struct dirent **a, const struct dirent **b) {
	struct stat astat, bstat;

	/* If we can't stat both of the files, give up and say they're equivalent. */
	if (stat((*a)->d_name, &astat) == -1 || stat((*b)->d_name, &bstat) == -1) {
		return 0;
	}

	return astat.st_ctime - bstat.st_ctime;
}

/* Only garbage collect LOG_PROBE files. */
int should_garbage_collect(const struct dirent *name) {
	char *extension = os_strrchr(name->d_name, '.');
	char buf[4];
	os_snprintf(buf, sizeof(buf), ".%d", LOG_PROBE);

	return os_strncmp(extension, buf, sizeof(buf)) == 0;
}

int garbage_collect_timestamp_files(const char *path) {
	int num_timestamp_files = 0, num_timestamp_files_deleted = 0, i = 0;
	struct dirent **namelist;
	char original_cwd[1024];
	char *filename;
	int error = 0;

	if (getcwd(original_cwd, sizeof(original_cwd)) == NULL) {
		wpa_printf(MSG_ERROR, "getcwd(): %s", strerror(errno));
		return -1;
	}

	if (chdir(request_logging_path) == -1) {
		wpa_printf(MSG_ERROR, "chdir(%s): %s",
		           request_logging_path, strerror(errno));
		return -1;
	}

	num_timestamp_files = scandir(request_logging_path, &namelist,
	                              should_garbage_collect, file_ctime_lt);
	for (i = 0; i < num_timestamp_files; ++i) {
		if (MAX_STEERING_TIMESTAMP_FILES <
		    /* The -2 is because scandir includes "." and "..". */
		    (num_timestamp_files - 2) - num_timestamp_files_deleted) {
			filename = namelist[i]->d_name;
			if (filename[0] != '.' && !error) {
				if (unlink(filename) == -1) {
					wpa_printf(MSG_ERROR, "unlink(%s): %s",
					           unlink(filename), strerror(errno));
					error = 1;
				} else {
					++num_timestamp_files_deleted;
				}
			}
		}
		os_free(namelist[i]);
	}
	os_free(namelist);

	if (chdir(original_cwd) == -1) {
		wpa_printf(MSG_ERROR, "chdir(%s): %s", original_cwd, strerror(errno));
		return -1;
	}

	return error ? -1 : num_timestamp_files_deleted;
}
