#!/bin/bash

function _mod_flame_linux()
{
	local here="${1}"
	local mod="${2}"
	local result_dir="${3}"

	local index=`from_mod_get_index "${mod}"`
	local name=`from_mod_get_name "${mod}"`
	local dir=`from_mod_get_dir "${mod}"`
	local conf=`from_mod_get_conf "${mod}"`
	local host=`from_mod_get_host "${mod}"`

	local local_mode=`is_local_host "${host}"`
	local gen_dir="${dir}/tmp/flame"

	local data_file="${gen_dir}/${name}_${index}.cpu.data"
	local path_prefix="${result_dir}/${name}_${index}.cpu"
	local copied_file="${path_prefix}.data"
	local perf_file="${path_prefix}.perf"
	local folded_file="${path_prefix}.folded"
	local result_file="${path_prefix}.svg"

	mkdir -p "${result_dir}"

	if [ "${local_mode}" == 'true' ]; then
		echo "=> sampling: ${name} #${index} ${dir}"
		local pid=`get_value "${dir}/proc.info" 'pid'`
		if [ -z "${pid}" ]; then
			echo "   error: fetch pid from proc.info failed"
			return 1
		fi
		mkdir -p "${gen_dir}"
		rm -f "${data_file}"
		local record_res=`perf record -F 400 -p "${pid}" -g -o "${data_file}" -- sleep "${sampling_sec}" 2>&1`
		if [ ! -f "${data_file}" ]; then
			echo "   error: perf record failed: ${record_res}"
			return 1
		fi
		cp -f "${data_file}" "${copied_file}"
	else
		echo "=> [${host}] sampling: ${name} #${index} ${dir}"
		local pid=`ssh_get_value_from_proc_info "${host}" "${dir}" 'pid'`
		if [ -z "${pid}" ]; then
			echo "   error: fetch pid from ${host}:${dir}/proc.info failed"
			return 1
		fi
		local record_res=`ssh_exe "${host}" "mkdir -p \"${gen_dir}\" && rm -f \"${data_file}\" && perf record -F 200 -p \"${pid}\" -g -o \"${data_file}\" -- sleep \"${sampling_sec}\" 2>&1"`
		local has_data=`ssh_exe "${host}" "test -f \"${data_file}\" && echo true"`
		if [ "${has_data}" != 'true' ]; then
			echo "   error: perf record failed: ${record_res} on ${host}"
			return 1
		fi
		rsync --quiet ${host}:"${data_file}" "${copied_file}"
	fi

	if [ ! -f "${copied_file}" ]; then
		echo "   error: file copy failed: ${record_res}"
		return 1
	fi
	perf script -i "${copied_file}" > "${perf_file}" 2>/dev/null
	if [ ! -f "${perf_file}" ]; then
		echo "   error: create ${perf_file} failed"
		return 1
	fi
	"${here}/stackcollapse-perf.pl" "${perf_file}" > "${folded_file}"
	if [ ! -f "${perf_file}" ]; then
		echo "   error: create ${folded_file} failed"
		return 1
	fi
	"${here}/flamegraph.pl" "${folded_file}" > "${result_file}"
	if [ ! -f "${perf_file}" ]; then
		echo "   error: create ${result_file} failed"
		return 1
	fi
	echo "   result: ${result_file}"
}

function cmd_ti_perf_flame()
{
	local ti_file="${1}"
	local ti_args="${2}"
	local cmd_mod_names="${3}"
	local cmd_hosts="${4}"
	local cmd_indexes="${5}"
	local mods="${6}"
	shift 6

	local sampling_sec="${1}"
	local result_dir="${2}"

	local here=`cd $(dirname ${BASH_SOURCE[0]}) && pwd`
	source "${here}"/_env.sh
	auto_error_handle

	if [ -z "${sampling_sec}" ]; then
		local sampling_sec='20'
	fi
	if [ -z "${result_dir}" ]; then
		local result_dir="${ti_file}.data/flame"
	fi

	if [ `uname` == "Darwin" ]; then
		echo "TODO: support perf/flame on Mac"
		return 1
	fi

	echo "${mods}" | while read mod; do
		_mod_flame_linux "${here}" "${mod}" "${result_dir}"
	done
}

cmd_ti_perf_flame "${@}"
