/*
 * 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/hw_features_common.h"
#include "common/ieee802_11_defs.h"
#include "hostapd.h"
#include "steering.h"

static int get_timestamp_filename(const u8 *mac,
                                  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(mac), type) < 0) {
		wpa_printf(MSG_ERROR, "os_snprintf couldn't format filename: %s",
		           strerror(errno));
		return 0;
	}

	return 1;
}

int write_timestamp_file(const u8 *mac,
                         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(mac, 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 (timestamp) {
		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 u8 *mac,
                               const struct hostapd_data *hapd,
                               logged_request_type type) {
	struct os_reltime now, prev_logged_timestamp, new_timestamp;
	int bandsteering_delay_seconds;
	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(mac, type, LOGGING_PATH, &prev_logged_timestamp) ||
	    os_reltime_expired(&now, &prev_logged_timestamp,
	                       BANDSTEERING_EXPIRATION_SECONDS)) {
		bandsteering_delay_seconds = BANDSTEERING_DELAY_SECONDS;
		if (experiment("WifiShortBandsteeringDelay")) {
			bandsteering_delay_seconds = 1;
		}
		new_timestamp.sec = now.sec + bandsteering_delay_seconds;
		new_timestamp.usec = now.usec;
		if (!write_timestamp_file(mac, hapd, type, &new_timestamp)) {
			wpa_printf(MSG_ERROR, "Failed to write timestamp file.");
			return 0;
		} else {
			wpa_printf(MSG_INFO, "Set steering timestamp for " MACSTR " (type=%d)",
			           MAC2STR(mac), type);
			return 1;
		}
	}
}

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

	if (!get_timestamp_filename(mac, 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 (timestamp) {
		if (fscanf(f, "%d %d", &timestamp->sec, &timestamp->usec) != 2) {
			wpa_printf(MSG_ERROR, "fscanf from %s: %s", filename, strerror(errno));
			success = 0;
		}
	}

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

	return success;
}

int delete_timestamp_file(const u8 *mac,
                          logged_request_type type,
                          steering_path_type path_type) {
	char filename[1024];
	struct stat st;

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

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

	if (unlink(filename) == -1) {
		wpa_printf(MSG_ERROR, "unlink(%s): %s", filename, strerror(errno));
		return 0;
	}

	return 1;
}

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) {
		if (errno != ENOENT) {
			wpa_printf(MSG_ERROR, "chdir(%s): %s",
			           request_logging_path, strerror(errno));
			return -1;
		} else {
			return 0;
		}
	}

	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", 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;
}
