/**
 * @file libperf_events/operf_stats.cpp
 * Management of operf statistics
 *
 * @remark Copyright 2012 OProfile authors
 * @remark Read the file COPYING
 *
 * Created on: June 11, 2012
 * @author Maynard Johnson
 * (C) Copyright IBM Corp. 2012
 */

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <errno.h>

#include "operf_stats.h"
#include "op_get_time.h"

unsigned long operf_stats[OPERF_MAX_STATS];

/**
 * operf_print_stats - print out latest statistics to operf.log
 */
using namespace std;

static string create_stats_dir(string const & cur_sampledir);
static void write_throttled_event_files(vector< operf_event_t> const & events,
                                        string const & stats_dir);

static void _write_stats_file(string const & stats_filename, unsigned long lost_sample_count)
{
	ofstream stats_file(stats_filename.c_str(), ios_base::out);
	if (stats_file.good()) {
		stats_file << lost_sample_count;
		stats_file.close();
	} else {
		cerr << "Unable to write to stats file " << stats_filename << endl;
	}
}

void operf_print_stats(string sessiondir, char * starttime, bool throttled,
                       vector< operf_event_t> const & events)
{
	string operf_log (sessiondir);
	unsigned long total_lost_samples = 0;
	bool stats_dir_valid = true;

	string stats_dir = create_stats_dir(sessiondir + "/" + "samples/current/");
	if (strcmp(stats_dir.c_str(), "") != 0) {
		// If there are throttled events print them
		write_throttled_event_files(events, stats_dir);
	} else {
		stats_dir_valid = false;
		perror("Unable to create stats dir");
	}

	operf_log.append("/samples/operf.log");
	FILE * fp = fopen(operf_log.c_str(), "a");
	if (!fp) {
		fprintf(stderr, "Unable to open %s file.\n", operf_log.c_str());
		return;
	}
	fprintf(fp, "\nProfiling started at %s", starttime);
	fprintf(fp, "Profiling stopped at %s", op_get_time());
	fprintf(fp, "\n-- OProfile/operf Statistics --\n");
	fprintf(fp, "Nr. non-backtrace samples: %lu\n", operf_stats[OPERF_SAMPLES]);
	fprintf(fp, "Nr. kernel samples: %lu\n", operf_stats[OPERF_KERNEL]);
	fprintf(fp, "Nr. user space samples: %lu\n", operf_stats[OPERF_PROCESS]);
	fprintf(fp, "Nr. samples lost due to sample address not in expected range for domain: %lu\n",
	       operf_stats[OPERF_INVALID_CTX]);
	fprintf(fp, "Nr. lost kernel samples: %lu\n", operf_stats[OPERF_LOST_KERNEL]);
	fprintf(fp, "Nr. samples lost due to sample file open failure: %lu\n",
		operf_stats[OPERF_LOST_SAMPLEFILE]);
	fprintf(fp, "Nr. samples lost due to no permanent mapping: %lu\n",
		operf_stats[OPERF_LOST_NO_MAPPING]);
	fprintf(fp, "Nr. user context kernel samples lost due to no app info available: %lu\n",
	       operf_stats[OPERF_NO_APP_KERNEL_SAMPLE]);
	fprintf(fp, "Nr. user samples lost due to no app info available: %lu\n",
	       operf_stats[OPERF_NO_APP_USER_SAMPLE]);
	fprintf(fp, "Nr. backtraces skipped due to no file mapping: %lu\n",
	       operf_stats[OPERF_BT_LOST_NO_MAPPING]);
	fprintf(fp, "Nr. hypervisor samples dropped due to address out-of-range: %lu\n",
	       operf_stats[OPERF_LOST_INVALID_HYPERV_ADDR]);
	fprintf(fp, "Nr. samples lost reported by perf_events kernel: %lu\n",
	       operf_stats[OPERF_RECORD_LOST_SAMPLE]);

	if (operf_stats[OPERF_RECORD_LOST_SAMPLE]) {
		fprintf(stderr, "\n\n * * * ATTENTION: The kernel lost %lu samples. * * *\n",
		        operf_stats[OPERF_RECORD_LOST_SAMPLE]);
		fprintf(stderr, "Decrease the sampling rate to eliminate (or reduce) lost samples.\n");
	} else if (throttled) {
		fprintf(stderr, "* * * * WARNING: Profiling rate was throttled back by the kernel * * * *\n");
		fprintf(stderr, "The number of samples actually recorded is less than expected, but is\n");
		fprintf(stderr, "probably still statistically valid.  Decreasing the sampling rate is the\n");
		fprintf(stderr, "best option if you want to avoid throttling.\n");
	}

	for (int i = OPERF_INDEX_OF_FIRST_LOST_STAT; i < OPERF_MAX_STATS; i++) {
		if (stats_dir_valid && operf_stats[i])
			_write_stats_file(stats_dir + "/" + stats_filenames[i], operf_stats[i]);
		total_lost_samples += operf_stats[i];
	}
	// Write total_samples into stats file if we see any indication of lost samples
	if (total_lost_samples)
		_write_stats_file(stats_dir + "/" + stats_filenames[OPERF_SAMPLES], operf_stats[OPERF_SAMPLES]);

	if (total_lost_samples > (int)(OPERF_WARN_LOST_SAMPLES_THRESHOLD
				       * operf_stats[OPERF_SAMPLES]))
		fprintf(stderr, "\nWARNING: Lost samples detected! See %s for details.\n", operf_log.c_str());

	fflush(fp);
	fclose(fp);
};

static void write_throttled_event_files(vector< operf_event_t> const & events,
                                        string const & stats_dir)
{
	string outputfile;
	ofstream outfile;
	string event_name;
	string throttled_dir;
	bool throttled_dir_created = false;
	int rc;

	throttled_dir =  stats_dir + "/throttled";

	for (unsigned index = 0; index < events.size(); index++) {
		if (events[index].throttled == true) {

			if (!throttled_dir_created) {
				rc = mkdir(throttled_dir.c_str(),
					   S_IRWXU | S_IRWXG
					   | S_IROTH | S_IXOTH);
				if (rc && (errno != EEXIST)) {
					cerr << "Error trying to create " << throttled_dir
					     << endl;
					perror("mkdir failed with");
					return;
				}
				throttled_dir_created = true;
			}

			/* Write file entry to indicate if the data sample was
			 * throttled.
			 */
			outputfile = throttled_dir + "/"
				+ events[index].name;

			outfile.open(outputfile.c_str());

			if (!outfile.is_open()) {
				cerr << "Internal error: Could not create " << outputfile
				     <<  strerror(errno) << endl;
			} else {
				outfile.close();
			}
		}
	  }
	if (throttled_dir_created) {
		cerr << "\nWARNING! Some of the events were throttled. "
		     << "Throttling occurs when\n";
		cerr << "the initial sample rate is too high, causing an "
		     << "excessive number of\n";
		cerr << "interrupts.  Decrease the sampling frequency. "
		     << "Check the directory\n";
		cerr << throttled_dir << "\n"
		     << "for the throttled event names.\n\n";
	}
};


static string create_stats_dir(string const & cur_sampledir)
{
	int rc;
	std::string stats_dir;

	/* Assumption: cur_sampledir ends in slash */
	stats_dir =  cur_sampledir + "stats";
	rc = mkdir(stats_dir.c_str(),
		   S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

	if (rc && (errno != EEXIST)) {
		cerr << "Error trying to create stats dir. " << endl;
		perror("mkdir failed with");
		return NULL;
	}
	return stats_dir;
}
