#! /usr/bin/env bash

# Copyright (C) 2007 Juan Manuel Borges Caño

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

H2I=${0##*/}
H2I_DESCRIPTION="Generate a simple info manual."
H2I_BUGREPORT="juanmabc3@gmail.com"
H2I_DATADIR="/usr/share/help2info"
H2I_VERSION="0.1.0"

function h2i_usage
{
	printf "Usage: $H2I [OPTION]... EXECUTABLE\n"
	printf "$H2I_DESCRIPTION\n"
	printf "\n"
 	printf "Mandatory arguments for long options are mandatory for short options too.\n"
	printf "  -d, --dircategory=DIRCATEGORY\tset info directory category\n"
	printf "  -n, --programname=PROGRAMNAME\tset full program name\n"
	printf "  -a, --author=AUTHOR\t\tset full author name\n"
	printf "  -c, --copyright=COPYRIGHT\tset copyright holder\n"
	printf "  -b, --bugreport=BUGREPORT\tset bug report address\n"
	printf "  -g, --generate=VERSION\tgenerate version.texi\n"
	printf "  -h, --help\t\t\tshows a help message\n"
	printf "  -v, --version\t\t\tshows the program version\n"
	printf "\n"
	printf "Report bugs to <$H2I_BUGREPORT>\n"
	exit 0;
}

function h2i_version
{
	printf "$H2I_VERSION\n"
	exit 0
}

function h2i_cat
{
	sed -e "s,^,$H2I: ," "$1"
}

function h2i_info
{
	echo "Try \`$H2I --help' for more information."
}

function h2i_error
{
	echo "$H2I: $@"; h2i_info; exit 1
}

function h2i_check_and_echo
{
	if [[ $? == 0 ]]
	then echo "done"
	else echo "error"; h2i_cat "$1"; h2i_info; exit 1
	fi
}

TEMP=$(getopt -o "d:n:a:c:b:g:hv" \
	      -l "dircategory:,programname:,author:,copyright:,bugreport:,generate:,help,version" -n "$H2I" -- "$@")
eval set -- "$TEMP"
while [[ -n "$1" ]]
do
	case "$1" in
		-"d" | --"dircategory") H2I_INFO_DIRCATEGORY="$2"; shift 2;;
		-"n" | --"programname") H2I_INFO_PROGRAM_NAME="$2"; shift 2;;
		-"a" | --"author") H2I_INFO_AUTHOR="$2"; shift 2;;
		-"c" | --"copyright") H2I_INFO_COPYRIGHT="$2"; shift 2;;
		-"b" | --"bugreport") H2I_INFO_BUGREPORT="$2"; shift 2;;
		-"g" | --"generate") H2I_INFO_VERSION="$2"; shift 2;;
		-"h" | --"help") h2i_usage; shift;;
		-"v" | --"version") h2i_version; shift;;
		--) shift; break;;
		*) printf "Internal error!\n"; exit 1;;
	esac
done

# capture output
if [[ -z $1 ]]
then
	h2i_error "you must specify a command"
fi
if ! which "$1" >/dev/null 2>&1
then
	h2i_error "$1: command not found"
fi
H2I_OUTPUT=$("$1" --help)

# get year
H2I_INFO_YEAR=$(LANG=C date '+%Y')

# get dircategory
if [[ -z $H2I_INFO_DIRCATEGORY ]]
then H2I_INFO_DIRCATEGORY="Insert dir category here"
fi

# get program name
if [[ -z $H2I_INFO_PROGRAM_NAME ]]
then H2I_INFO_PROGRAM_NAME=${1##*/}
fi

# get author
if [[ -z $H2I_INFO_AUTHOR ]]
then H2I_INFO_AUTHOR=$(grep $(whoami) /etc/passwd | cut -d':' -f5 | cut -d',' -f1)
fi
if [[ -z $H2I_INFO_AUTHOR ]]
then H2I_INFO_AUTHOR="Insert author name here"
fi

# get copyright holder
if [[ -z $H2I_INFO_COPYRIGHT ]]
then H2I_INFO_COPYRIGHT=$(grep $(whoami) /etc/passwd | cut -d':' -f5 | cut -d',' -f1)
fi
if [[ -z $H2I_INFO_COPYRIGHT ]]
then H2I_INFO_COPYRIGHT="Insert copyright holder here"
fi

# get usage
# Usage:
#   or:
function h2i_get_usage
{
	while IFS=$'\n' read line
	do
		echo "$line"
	done < <(egrep -i '^usage:|^  or:' <<< "$1")
}
H2I_INFO_USAGE=$(h2i_get_usage "$H2I_OUTPUT")

# get description
# comes after usage and ends with a blank line
function h2i_get_description
{
	array=($(egrep -ni '^usage:|^  or:' <<< "$1" | cut -d':' -f1 | paste -s -d' '))
	for element in ${array[*]}
	do
		let H2I_LNEXT=$element+1
		if ! sed -n ${H2I_LNEXT}p <<< "$1" | egrep -qi '^usage:|^  or:'
			then break;
		fi
	done
	H2I_START=$H2I_LNEXT
	H2I_END=$(echo "$1" | grep -nm 1 '^$' | cut -d':' -f1)
	echo "$1" | sed -n ${H2I_START},${H2I_END}p
}
H2I_INFO_DESCRIPTION=$(h2i_get_description "$H2I_OUTPUT")

# get options (starts after the description with the mandatory line for long and short options and ends with the empty line before the bug report address, last line if present)
function h2i_get_options_and_comments
{
	let H2I_START=$(grep -nm 1 '^$' <<< "$1" | cut -d':' -f1)+1
	H2I_LAST_LINE=$(tail -1 <<< "$1")
       	if grep -qi 'report bugs' <<< "$H2I_LAST_LINE"
	then
		let H2I_END=$(wc -l <<< "$1")-1
	else
		H2I_END=$(wc -l <<< "$1")
	fi
	sed -n ${H2I_START},${H2I_END}p <<< "$1"
}
H2I_PROGRAM_OPTIONS_AND_COMMENTS=$(h2i_get_options_and_comments "$H2I_OUTPUT")

# convert options to info

function h2i_parse_args
{
	printf "@item "
	line=$(sed -e 's,^[[:space:]]\+,,' <<< "$1")
	while grep -qe '^--\?\w\+, ' <<< "$line"
	do
		echo -n "$(cut -d' ' -f1 <<< "$line") "
		line=$(cut -d' ' -f2- <<< "$line" | sed -e 's,^[[:space:]]\+,,g')
	done
	if grep -qe '^--\?\w\+' <<< "$line"
	then
		sed -e 's,^\([^[:space:]]\+\)[[:space:]]\+.*$,\1,' <<< "$line"
		line=$(sed -e 's,^[^[:space:]]\+[[:space:]]\+\(.*\)$,\1,' <<< "$line")
	else
		echo
	fi
	echo "$line"
}

function h2i_parse_options_and_comments
{
	while IFS=$'\n' read line
	do
		if [[ -n $H2I_OPTIONS_ENDED ]]
		then
			line=$(sed -e 's,[[:space:]]\+, ,g' -e 's,^ ,,' <<< "$line")
			echo "$line"
		else
			if grep -qe '^  -\w\+' <<< "$line"
			then
				if [[ -z $H2I_OPTIONS_STARTED ]]
				then echo "@table @code"; H2I_OPTIONS_STARTED="true"
				fi
				h2i_parse_args "$line"
			else
				if grep -qe '^      --\w\+' <<< "$line"
				then
					if [[ -z $H2I_OPTIONS_STARTED ]]
					then echo "@table @code"; H2I_OPTIONS_STARTED="true"
					fi
					h2i_parse_args "$line"
				else
					if grep -qe '^\w\+' <<< "$line"
					then 
						if [[ -z $H2I_OPTIONS_STARTED ]]
						then echo "$line"; echo; echo "@table @code"; H2I_OPTIONS_STARTED="true"
						else
							if [[ -z $H2I_OPTIONS_ENDED ]]
							then echo "@end table"; echo; H2I_OPTIONS_ENDED="true"
							fi
							if grep -qi 'options:' <<< "$line"
							then
								line=$(sed -e 's,[[:space:]]\+, ,g' -e 's,^ ,,' <<< "$line")
								echo "$line"; echo; echo "@table @code";
								unset -v H2I_OPTIONS_ENDED ;
							else
								if [[ -z $H2I_OPTIONS_INFO_STARTED ]]
								then echo "@verbatim"; H2I_OPTIONS_INFO_STARTED="true"
								fi
							       	line=$(sed -e 's,[[:space:]]\+, ,g' -e 's,^ ,,' <<< "$line")
								echo "$line"
							fi
						fi
					else 
						line=$(sed -e 's,[[:space:]]\+, ,g' -e 's,^ ,,' <<< "$line"); echo "$line";
					fi
				fi
			fi
		fi
	done <<< "$1"
	if [[ -n $H2I_OPTIONS_INFO_STARTED ]]; then echo "@end verbatim"; else echo "@end table"; fi
}
H2I_INFO_OPTIONS_AND_COMMENTS=$(h2i_parse_options_and_comments "$H2I_PROGRAM_OPTIONS_AND_COMMENTS")

# convert bugreport addres to info
function h2i_parse_bugreport()
{
	H2I_COMMENT=$(tail -n 1 <<< "$1")
	if grep -qi 'report bugs' <<< "$H2I_COMMENT"
	then cut -d'<' -f2 <<< "$H2I_COMMENT" | cut -d'>' -f1 | sed -e 's,\([^@]\+@\),\1@,g'
	else echo "Insert your bug report address here"
	fi
}

if [[ -z $H2I_INFO_BUGREPORT ]]
then H2I_INFO_BUGREPORT=$(h2i_parse_bugreport "$H2I_OUTPUT")
fi

# create the tmp log
H2I_ERROR_LOG=$(mktemp)

# generate the texi file
if [[ -a ${H2I_INFO_PROGRAM_NAME}.texi ]]
then
	h2i_error "${H2I_INFO_PROGRAM_NAME}.texi: file exists"
else
	printf "Creating ${H2I_INFO_PROGRAM_NAME}.texi..."
		cat 2>> "$H2I_ERROR_LOG" > "${H2I_INFO_PROGRAM_NAME}.texi" <<-EOF
		\input texinfo	@c -*-texinfo-*-
		@comment It was generated by $H2I $H2I_VERSION.
		@comment %**start of header
		@setfilename ${H2I_INFO_PROGRAM_NAME}.info
		@include version.texi
		@settitle $H2I_INFO_PROGRAM_NAME @value{VERSION}
		@syncodeindex pg cp
		@comment %**end of header
		@copying
		This manual is for $H2I_INFO_PROGRAM_NAME
		(version @value{VERSION}, @value{UPDATED}),
		which is a program that $H2I_INFO_DESCRIPTION

		Copyright @copyright{} $H2I_INFO_YEAR $H2I_INFO_COPYRIGHT

		@quotation
		Permission is granted to copy, distribute, and/or modify this document
		under the terms of the GNU Free Documentation License, Version 1.2 or
		any later version published by the Free Software Foundation; with no
		Invariant Sections, with the Front-Cover Texts being \`\`A Manual,''
		and with the Back-Cover Texts as in (a) below. A copy of the
		license is included in the section entitled \`\`GNU Free Documentation
		License.''

		(a) The Back-Cover Text is: \`\`You have freedom to copy and modify
		this Manual, like GNU software.''
		@end quotation
		@end copying
		@dircategory $H2I_INFO_DIRCATEGORY
		@direntry
		* $H2I_INFO_PROGRAM_NAME: ($H2I_INFO_PROGRAM_NAME). $H2I_INFO_DESCRIPTION
		@end direntry

		@titlepage
		@title $H2I_INFO_PROGRAM_NAME
		@subtitle for version @value{VERSION}, @value{UPDATED}
		@author $H2I_INFO_AUTHOR (@email{$H2I_INFO_BUGREPORT})
		@page
		@vskip 0pt plus 1filll
		@insertcopying
		@end titlepage

		@contents

		@ifnottex
		@node Top
		@top $H2I_INFO_PROGRAM_NAME
		@insertcopying
		@end ifnottex

		@menu
		* Introduction:: Introduction.
		* Invoking $H2I_INFO_PROGRAM_NAME::	Invocation.
		* Examples:: Some samples of use.
		* Reporting Bugs:: Reporting bugs
		* Copying This Manual:: The license for this documentation.
		@end menu

		@node Introduction 
		@chapter Introduction
		@pindex introduction
		@cindex introduction
		$H2I_INFO_DESCRIPTION

		@node Invoking $H2I_INFO_PROGRAM_NAME
		@chapter Invoking $H2I_INFO_PROGRAM_NAME
		@pindex invoking
		@cindex invoking @command{$H2I_INFO_PROGRAM_NAME}
		@verbatim
		$H2I_INFO_USAGE
		@end verbatim

		@command{$H2I_INFO_PROGRAM_NAME} may be invoked with the following command-line options:

		$H2I_INFO_OPTIONS_AND_COMMENTS

		@node Examples
		@chapter Examples
		@pindex examples
		@cindex examples
		Insert your examples here

		@node Reporting Bugs
		@chapter Reporting Bugs
		@pindex bugs
		@cindex reporting bugs
		Email bug reports to @email{$H2I_INFO_BUGREPORT}. Be sure to include the word @dfn{$H2I_INFO_PROGRAM_NAME} somewhere in the @code{Subject:} field. Also, please include the output of @samp{$H2I_INFO_PROGRAM_NAME --version} in the body of your report if at all possible.


		@node Copying This Manual

		@appendix Copying This Manual
		@menu
		* GNU Free Documentation License::	License for copying this manual.
		@end menu

		@include fdl.texi

		@bye
		EOF
	h2i_check_and_echo "$H2I_ERROR_LOG"
fi

# generate fdl.texi
if [[ -a fdl.texi ]]
then
	h2i_error "fdl.texi: file exists"
else
	printf "Creating fdl.texi..."
		cp "$H2I_DATADIR/fdl.texi" . 2>> "$H2I_ERROR_LOG" 
	h2i_check_and_echo "$H2I_ERROR_LOG"
fi

# generate version.texi if requested
if [[ -n $H2I_INFO_VERSION ]]
then
	if [[ -a version.texi ]]
	then
		h2i_error "version.texi: file exists"
	else
		H2I_INFO_UPDATED=$(date '+%-e %B %Y')
		printf "Creating version.texi..."
			cat 2>> "$H2I_ERROR_LOG" > "version.texi" <<-EOF
			@set UPDATED $H2I_INFO_UPDATED
			@set VERSION $H2I_INFO_VERSION
			EOF
		h2i_check_and_echo "$H2I_ERROR_LOG"
	fi
fi
