#!/usr/bin/python

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Author: Jan Kaluza

import os
import sys
import subprocess
import platform

# Do not forget to change VERSION also in setup.py file
VERSION = "0.3"

def get_kernel_release():
	p = subprocess.Popen(["uname", "-r"], stdout=subprocess.PIPE)
	kernel_release, err = p.communicate()
	return kernel_release

def get_rpm_vr(n):
	p = subprocess.Popen(["rpm", "-q", n], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
	vr, err = p.communicate()
	if p.returncode != 0:
		return ""
	return vr[len(n) + 1 : -1]

def is_debug_installed():
	packages = ""

	distname = platform.linux_distribution()[0]
	if distname == "Fedora":
		for p in ("apr", "apr-util", "httpd"):
			dbg_rpm_vr = get_rpm_vr(p + "-debuginfo")
			if len(dbg_rpm_vr) == 0:
				rpm_vr = get_rpm_vr(p)
				if len(rpm_vr) == 0:
					packages += " " + p + " " + p + "-debuginfo"
				else:
					packages += " " + p + "-debuginfo-" + rpm_vr

		if os.system("rpm -q kernel-debuginfo|grep `uname -r` > /dev/null"):
			packages += " kernel-debuginfo-" + get_kernel_release()

		if packages != "":
			print "You have to install following debuginfo packages to be able to use httpdtap:"
			print "yum install" + packages
			return False

	# If we don't support this distribution, just return True and hope
	# the packages are installed.
	return True

def get_scripts_in_dir(scripts, d):
	if not os.path.exists(d):
		return scripts
	for script in os.listdir(d):
		if not script.endswith(".stp"):
			continue
		scripts[script[:-4]] = d + "/" + script
	return scripts

def get_httpd_version():
	try:
		p = subprocess.Popen(["httpd", "-v"], stdout=subprocess.PIPE)
	except:
		print "Cannot find 'httpd' executable"
		sys.exit(-4)
	out, err = p.communicate()
	if p.returncode != 0:
		print "Cannot execute 'httpd -v' to detect httpd version"
		sys.exit(-3)

	if out.find("/2.2") != -1:
		return "22"
	if out.find("/2.4") != -1:
		return "24"

	print "Unable to detect httpd version!"
	sys.exit(-2)

def get_available_scripts():
	version = get_httpd_version();

	scripts = {}
	scripts = get_scripts_in_dir(scripts, "./scripts-" + version)
	scripts = get_scripts_in_dir(scripts, "/usr/share/httpdtap/scripts-" + version)
	return scripts

def get_summary(script):
	summary = ""
	f = open(script, "r")
	for line in f.readlines():
		if line.find("Summary:") == -1:
			continue
		summary = line[line.find("Summary:") + 8:].strip()
		break
	f.close()
	return summary;

def get_description(script):
	desc = ""
	in_desc = False
	f = open(script, "r")
	for line in f.readlines():
		if not in_desc and line.find("Description:") == -1:
			continue
		if line.find("*/") != -1:
			break
		if not in_desc:
			desc += line[line.find("Description:") + 12:].strip() + "\n"
		else:
			desc += line[line.find("*") + 1:].strip() + "\n"
		in_desc = True
	f.close()
	return desc

def show_scripts_summary(scripts):
	keys = scripts.keys()
	keys.sort()
	for k in keys:
		print k, "-", get_summary(scripts[k])

scripts = get_available_scripts()

if len(sys.argv) == 1 or not scripts.has_key(sys.argv[1]):
	if len(sys.argv) == 3 and sys.argv[1] == "help" and scripts.has_key(sys.argv[2]):
		print get_summary(scripts[sys.argv[2]])
		print get_description(scripts[sys.argv[2]])
	elif len(sys.argv) == 2 and (sys.argv[1] == "--version" or sys.argv[1] == "-v"):
		print "httpdtap version", VERSION
		print "Released under ASL 2.0 license"
		print "https://github.com/hanzz/httpdtap"
	else:
		print "Usage:", sys.argv[0], "<command> [[stap_argument], ...] [[arg], ...]"
		print "      ", sys.argv[0], "help <command>"
		print "      ", sys.argv[0], "--version"
		print "For list of stap arguments, see 'man stap'."
		print "Available commands:"
		show_scripts_summary(scripts)
	sys.exit(0)

if os.geteuid() != 0:
	print('You are trying to run httpdtap as a normal user.')
	print('You should either be root, or be part of the group "stapusr" and possibly one of the groups "stapsys" or "stapdev".')
	# print('Alternatively, you may specify --runtime=dyninst for userspace probing.')
	print("Try 'stap --help' for more information.")
	sys.exit(-1)

if not is_debug_installed():
	sys.exit(-2)

command = "stap -s1 " + scripts[sys.argv[1]] + " " + " ".join(sys.argv[1:])
#print "Executing:", command
sys.exit(os.system(command))
