#!/bin/sh
# Copyright (C) 2005, Michiel Lieuwe de Boer
# Copyright (C) 2005-2015, Stefan Lippers-Hollmann <s.l-h@gmx.de>

# 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.

# override tool behaviour through distro-defaults
FLL_IRC_SERVER="irc.oftc.net"
FLL_IRC_PORT="6697"
FLL_IRC_CHANNEL="#aptosid"
FLL_DISTRO_NAME="aptosid"
[ -r /etc/default/distro ] && . /etc/default/distro

# work around transitioning side effects
[ "${FLL_DISTRO_NAME}" = "sidux" ] && FLL_DISTRO_NAME="aptosid"
[ "${FLL_IRC_CHANNEL}" = "#sidux" ] && FLL_IRC_CHANNEL="#aptosid"

# define user settings
NICK="Web-${FLL_DISTRO_NAME}$(mawk 'BEGIN{print int(1000 * rand())}')"
XTERM_OPT="-e"


# determine system status
MKTEMP="$(which mktemp)"			|| MKTEMP="/bin/mktemp"
SSFTSH="$(which ssft.sh)"			|| SSFTSH="/usr/bin/ssft.sh"
SU="$(which su)"				|| SU="/bin/su"
XTERMINAL="$(which x-terminal-emulator)"	|| XTERMINAL="/usr/bin/x-terminal-emulator"

HEXCHAT="$(which hexchat)"			|| HEXCHAT="/usr/bin/hexchat"
IRSSI="$(which irssi)"				|| IRSSI="/usr/bin/irssi"
KONVERSATION="$(which konversation)"		|| KONVERSATION="/usr/bin/konversation"
WEECHAT="$(which weechat-curses)"		|| WEECHAT="/usr/bin/weechat-curses"
SRAIN="$(which srain)"				|| SRAIN="/usr/bin/srain"
KVIRC="$(which kvirc)"				|| kvirc="/usr/bin/kvirc"

# internal functions
irc_irssi()
{
	TERM_TYPE="utf-8"
	#TERM_TYPE="8bit"
	IRSSICFG="$($MKTEMP -dp /tmp/ .irssi-XXXXXXXXXX)"

	CTCPS=0
	if [ -e /etc/aptosid-version ]; then
		QUITMSG="$(cat /etc/aptosid-version) | http://aptosid.com"
	else
		QUITMSG="http://aptosid.com"
	fi

	cat <<_EOF_ >"$IRSSICFG/config"
servers = (
  {
    address = "$FLL_IRC_SERVER";
    chatnet = "oftc";
    port = "$FLL_IRC_PORT";
    autoconnect = "yes";
  }
);

chatnets = {
  oftc = {
    type = "IRC";
    max_kicks = "4";
    max_modes = "4";
    max_msgs = "1";
    max_whois = "1";
  };
};

channels = (
  { name = "$FLL_IRC_CHANNEL"; chatnet = "oftc"; autojoin = "yes"; }
);
_EOF_

	# See also special aptosid aliases in here, like "/IBS", "/IBV", "/IB", "/GFX", "/SND", and "/X"
	cat <<"_EOF_" >>"$IRSSICFG/config"
aliases = {
  J = "join";
  WJOIN = "join -window";
  WQUERY = "query -window";
  LEAVE = "part";
  BYE = "quit";
  EXIT = "quit";
  SIGNOFF = "quit";
  DESCRIBE = "action";
  DATE = "time";
  HOST = "userhost";
  LAST = "lastlog";
  SAY = "msg *";
  WI = "whois";
  WII = "whois $0 $0";
  WW = "whowas";
  W = "who";
  N = "names";
  M = "msg";
  T = "topic";
  C = "clear";
  CL = "clear";
  K = "kick";
  KB = "kickban";
  KN = "knockout";
  BANS = "ban";
  B = "ban";
  MUB = "unban *";
  UB = "unban";
  IG = "ignore";
  UNIG = "unignore";
  SB = "scrollback";
  UMODE = "mode $N";
  WC = "window close";
  WN = "window new hide";
  SV = "say Irssi $J ($V) - http://irssi.org/";
  GOTO = "sb goto";
  CHAT = "dcc chat";
  RUN = "SCRIPT LOAD";
  UPTIME = "eval exec - expr `date +%s` - \\$F | awk '{print \"Irssi uptime: \"int(\\\\\\$1/3600/24)\"d \"int(\\\\\\$1/3600%24)\"h \"int(\\\\\\$1/60%60)\"m \"int(\\\\\\$1%60)\"s\" }'";
  CALC = "exec - if which bc &>/dev/null\\; then echo '$*' | bc | awk '{print \"$*=\"$$1}'\\; else echo bc was not found\\; fi";
  SBAR = "STATUSBAR";
  INVITELIST = "mode $C +I";
  Q = "QUERY";
  QUIT = "foreach window /part;/quit";
  INFOBASH = "/exec -o infobash $*";
  X = "QUIT";
};

statusbar = {
  # formats:
  # when using {templates}, the template is shown only if it's argument isn't
  # empty unless no argument is given. for example {sb} is printed always,
  # but {sb $T} is printed only if $T isn't empty.

  items = {
    # start/end text in statusbars
    barstart = "{sbstart}";
    barend = "{sbend}";

    topicbarstart = "{topicsbstart}";
    topicbarend = "{topicsbend}";

    # treated "normally", you could change the time/user name to whatever
    time = "{sb $Z}";
    user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}";

    # treated specially .. window is printed with non-empty windows,
    # window_empty is printed with empty windows
    window = "{sb $winref:$itemname{sbmode $M}}";
    window_empty = "{sb $winref{sbservertag $tag}}";
    prompt = "{prompt $[.15]itemname}";
    prompt_empty = "{prompt $winname}";
    topic = " $topic";
    topic_empty = " Irssi v$J - http://irssi.org/help/";

    # all of these treated specially, they're only displayed when needed
    lag = "{sb Lag: $0-}";
    act = "{sb Act: $0-}";
    more = "-- more --";
  };

  # there's two type of statusbars. root statusbars are either at the top
  # of the screen or at the bottom of the screen. window statusbars are at
  # the top/bottom of each split window in screen.
  default = {
    # the "default statusbar" to be displayed at the bottom of the window.
    # contains all the normal items.
    window = {
      disabled = "no";

      # window, root
      type = "window";
      # top, bottom
      placement = "bottom";
      # number
      position = "1";
      # active, inactive, always
      visible = "active";

      # list of items in statusbar in the display order
      items = {
        barstart = { priority = "100"; };
        time = { };
        user = { };
        window = { };
        window_empty = { };
        lag = { priority = "-1"; };
        act = { priority = "10"; };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # statusbar to use in inactive split windows
    window_inact = {
      type = "window";
      placement = "bottom";
      position = "1";
      visible = "inactive";
      items = {
        barstart = { priority = "100"; };
        window = { };
        window_empty = { };
        more = { priority = "-1"; alignment = "right"; };
        barend = { priority = "100"; alignment = "right"; };
      };
    };

    # we treat input line as yet another statusbar :) It's possible to
    # add other items before or after the input line item.
    prompt = {
      type = "root";
      placement = "bottom";
      # we want to be at the bottom always
      position = "100";
      visible = "always";
      items = {
        prompt = { priority = "-1"; };
        prompt_empty = { priority = "-1"; };
        # treated specially, this is the real input line.
        input = { priority = "10"; };
      };
    };

    # topicbar
    topic = {
      type = "root";
      placement = "top";
      position = "1";
      visible = "always";
      items = {
        topicbarstart = { priority = "100"; };
        topic = { };
        topic_empty = { };
        topicbarend = { priority = "100"; alignment = "right"; };
      };
    };
  };
};
_EOF_

	cat <<_EOF_ >>"$IRSSICFG/config"
settings = {
  core = {
    real_name = "aptosid user";
    user_name = "aptosid";
    nick = "$NICK";
    quit_message = "$QUITMSG";
  };

  "irc/core" = { part_message = "$QUITMSG"; };
  
  "irc/dcc" = {
    dcc_upload_path = "/tmp";
    dcc_download_path = "/tmp";
    dcc_autoget = "no";
    dcc_autochat_masks = "*";
    dcc_autoget_masks = "= *";
  };
  "fe-text" = { term_type = "$TERM_TYPE"; };
  "fe-common/core" = { completion_char = ","; };
  
};
logs = { };

windows = {
  2 = {
    items = (
      {
        type = "CHANNEL";
        chat_type = "IRC";
        name = "$FLL_IRC_CHANNEL";
        tag = "oftc";
      }
    );
  };
  1 = { immortal = "yes"; name = "(status)"; level = "ALL"; };
};
mainwindows = { 2 = { first_line = "1"; lines = "47"; }; };
_EOF_

	[ "$CTCPS" -eq 0 ] && echo 'ignores = ( { level = "CTCPS"; } );' >>"$IRSSICFG/config"

	"$IRSSI" --home="$IRSSICFG"
	RETC="$?"
	rm -rf "$IRSSICFG"
	[ "$RETC" -ne 0 ] && return 127 || exit 0
}

# internal functions
irc_konversation()
{
	exec "$KONVERSATION" --ssl --server "$FLL_IRC_SERVER" --port "$FLL_IRC_PORT" --channel "$FLL_IRC_CHANNEL" --nick "$NICK"
}

irc_kvirc()
{
	if [ ! -d "/home/$USER/.config/KVIrc/config" ]; then
		mkdir -p "/home/$USER/.config/KVIrc/config"
		cat  << _EOF_ >> "/home/$USER/.config/KVIrc/config/serverdb.kvc"
[OFTC]
0_Port=$FLL_IRC_PORT
0_Hostname=$FLL_IRC_SERVER
0_Nick=$NICK
NServers=1
0_AutoConnect=true
0_Description=OFTC
0_SSL=true
0_AutoJoinChannels=$FLL_IRC_CHANNEL
0_Id=$(mawk 'BEGIN{print int(1000 * rand())}')
0_RealName=$NICK
0_User=$NICK
0_AlternativeNick=${NICK}_
_EOF_
		cat  << _EOF_ >> "/home/$USER/.config/KVIrc/config/main.kvc"
[Frame]
boolShowTipAtStartup=false
boolShowServersConnectDialogOnStart=false
boolShowChannelsJoinOnIrc=false
boolConfirmCloseWhenThereAreConnections=false
boolDoNotSuggestRestoreDefaultScript=true
_EOF_
	fi

	exec "$KVIRC"
}

irc_hexchat()
{
	if [ -e "/home/$USER/.config/hexchat/hexchat.conf" ]; then
		sed -i	-e "/^irc_nick.*/d" \
			-e "/^irc_user_name.*/d" \
			-e "/^irc_real_name.*/d" \
			-e "/^tab_layout.*/d" \
				/home/$USER/.config/hexchat/hexchat.conf

	else
		mkdir -p /home/$USER/.config/hexchat
		touch /home/$USER/.config/hexchat/hexchat.conf
	fi

	echo "irc_nick1 = $NICK" >> /home/$USER/.config/hexchat/hexchat.conf
	echo "irc_nick2 = ${NICK}_" >> /home/$USER/.config/hexchat/hexchat.conf
	echo "irc_nick3 = ${NICK}__" >> /home/$USER/.config/hexchat/hexchat.conf
	echo "irc_user_name = $NICK" >> /home/$USER/.config/hexchat/hexchat.conf
	echo "irc_real_name = $NICK" >> /home/$USER/.config/hexchat/hexchat.conf
	echo "tab_layout = 0" >> /home/$USER/.config/hexchat/hexchat.conf

	exec "$HEXCHAT" --url=ircs://"$FLL_IRC_SERVER":"$FLL_IRC_PORT"/"$FLL_IRC_CHANNEL"
}

irc_srain()
{
	if [ ! -e "/home/$USER/.config/srain/srain.cfg" ]; then
		mkdir -p "/home/$USER/.config/srain"
		touch "/home/$USER/.config/srain/srain.cfg"
		cat > "/home/$USER/.config/srain/srain.cfg" <<_EOF_
auto-connect = [ "OFTC" ]
log = {
  prompt-color = true
}
server-list =
(
  {
    name = "OFTC"
    addresses = ["$FLL_IRC_SERVER:$FLL_IRC_PORT"]
    tls = true
    encoding = "utf-8"
    auto-join = ["$FLL_IRC_CHANNEL"]
    user = {
      nickname = "$NICK"
      username = "$NICK"
      realname = "$NICK"
    }
  }
)
_EOF_
	fi

	exec "$SRAIN"
}

##############################################################################
#                               int main(void);                              #
##############################################################################

# yes, this stuff is elementary
if [ -z "$DISPLAY" ]; then
	for i in "$SSFTSH" "$SU"; do
		if [ ! -x "$i" ]; then
			echo "$i: missing, terminate abnormally"		1>&2
			exit 999
		fi
	done
else
	for i in "$SSFTSH" "$XTERMINAL" "$SU"; do
		if [ ! -x "$i" ]; then
			echo "$i: missing, terminate abnormally"		1>&2
			exit 998
		fi
	done
fi

if [ "$1" = "--tty" ]; then
	DISPLAY=""
fi

# initialize ssft
. "$SSFTSH"
[ -n "$SSFT_FRONTEND" ] ||  SSFT_FRONTEND="$(ssft_choose_frontend)"

# are you insane?
if [ "`id -u`" = "0" ]; then
	echo "ROOOOOOOOOOOOT has landed!"					1>&2
	echo ""									1>&2
	echo "Don't ever call any IRC client as root"				1>&2

	if [ -n "$DISPLAY" ]; then
		ssft_display_message "ERROR" "ROOOOOOOOOOOOT has landed!\n\nDon't ever call any IRC client as root"
	fi

	exit 996
fi

# choose your nick
SSFT_DEFAULT="$NICK"
ssft_read_string "${FLL_DISTRO_NAME} IRC Chat" "Choose your nick" || exit 0
NICK="$SSFT_RESULT"

# try to start your irc client
if [ -z "$DISPLAY" ]; then
	# tty
	if [ -x "$IRSSI" ]; then
		irc_irssi
		exit "$?"
	fi

	[ -x "$WEECHAT" ] && \
		exec $WEECHAT "ircs://$NICK@$FLL_IRC_SERVER:$FLL_IRC_PORT/$FLL_IRC_CHANNEL"
else
	[ -x "$HEXCHAT" ] && irc_hexchat
	[ -x "$SRAIN" ] && irc_srain
	[ -x "$KVIRC" ] && irc_kvirc
	[ -x "$KONVERSATION" ] && irc_konversation

	# nasty fallback, but well - it works ;)
	exec $XTERMINAL $XTERM_OPT ${0} --tty
fi

# Oops...
echo "ERROR: failed to start any suitable IRC Client"				1>&2
for i in "$SSFTSH" "$IRSSI" "$KONVERSATION" "$WEECHAT" "$XCHAT"; do
	if [ -x "$i" ]; then
		echo "$i: found."
	else
		echo "$i: NOT found."						1>&2
	fi
done
