#!/bin/bash
# gemini to gopher proxy

proxyhost="localhost"
proxyport="77"

function info_text {
   printf "i%s\t\tnone\t0\r\n" "$1"
}

function link_file {
   printf "0%s\t%s\tlocalhost\t77\r\n" "$1" "$2"
}

read gemini_url
gemini_url=$(echo "$gemini_url" | tr -d '\r\n')
if [ "$gemini_url" == "" ]
then
   gemini_url="gemini://zaibatsu.circumlunar.space/~solderpunk/gemini/servers/"
fi
read gemini_host gemini_path <<< $(echo "$gemini_url" | sed -r 's#^(src:)*gemini://([^/]+)(.*)$#\2 \3#gi')

if [[ "$gemini_url" == src:* ]]
then
   gemini_url=$(echo "$gemini_url" | cut -b 5-)
   gemini_raw=1
elif [[ "$gemini_url" == url:* ]]
then
   printf "<!doctype html><meta http-equiv='refresh' content='3; url=%s'>" "$(echo "$gemini_url" | cut -b 5-)"
   exit 0
fi
# if [[ "$gemini_path" == "" ]]
# then
#   gemini_path="/" # workaround for relative links at root
# fi
printf "%s\r\n" "$gemini_url" | timeout 20 openssl s_client -quiet -ign_eof -connect $gemini_host:1965 2> /dev/null 1> /dev/shm/gemini.tmp
read gemini_status gemini_meta <<< $(head -n 1 /dev/shm/gemini.tmp | tr -d '\r\n')
# printf "Status: %s, Meta: %s\n" $gemini_status $gemini_meta
case "$gemini_status" in
   1*)
       info_text "Input not implemented"
       ;;
   2*)
       if [ "$gemini_raw" == "1" ]
       then
           tail -n +2 /dev/shm/gemini.tmp
       elif [ "$gemini_meta" == "text/gemini" ]; then
           info_text "Viewing $gemini_url"
           link_file "View source" "src:$gemini_url"
           tail -n +2 /dev/shm/gemini.tmp | sed -rn ':start
           s/\r$//gi;
           /^=>[[:space:]]*gemini:.*$/ {
               s/=>[[:space:]]*([^[:space:]]*)([[:space:]]+(.*))*$/1\3 (\1)\t\1\t'"$proxyhost\t$proxyport"'\r/gi;
               p;
               n;
               b start
           };
           /^=>[[:space:]]*(http|https|gopher|telnet|mailto|ssh).*$/ {
               s/=>[[:space:]]*([^[:space:]]*)([[:space:]]+(.*))*$/h\3 (\1)\turl:\1\t'"$proxyhost\t$proxyport"'\r/gi;
               p;
               n;
               b start
           };
           /^=>[[:space:]]*\/.*$/ {
               s#=>[[:space:]]*([^[:space:]]*)([[:space:]]+(.*))*$#1\3 (gemini://'"$gemini_host"'\1)\tgemini://'"$gemini_host"'\1\t'"$proxyhost\t$proxyport"'\r#gi;
               p;
               n;
               b start
           };
           /^=>[[:space:]]*.*$/ {
               s#=>[[:space:]]*([^[:space:]]*)([[:space:]]+(.*))*$#1\3 (gemini://'"$gemini_host$gemini_path"'/\1)\tgemini://'"$gemini_host$gemini_path"'/\1\t'"$proxyhost\t$proxyport"'\r#gi;
               s#([^:])//#\1/#gi;
               p;
               n;
               b start
           };
           s/^(.*)$/i\1\t\tnone\t0\r/gi;
           p'
       else
           info_text "You're gonna view ${gemini_meta} file"
           link_file "$gemini_url" "src:$gemini_url"
       fi
       ;;
   3*)
       case "$gemini_meta" in
           gemini://*)
               gemini_redirect="$gemini_meta"
               ;;
           *)
               gemini_redirect="gemini://$gemini_host$gemini_meta"
               ;;
       esac
       info_text "Redirecting to $gemini_redirect..."
       # $0 "$gemini_meta"
       printf "%s\r\n" "$gemini_redirect" | "$0"
       # printf "1Proceed to %s\t%s\tlocalhost\t77\r\n" "$gemini_redirect" "$gemini_redirect"
       ;;
   4*|5*)
       info_text "Error: $gemini_meta!\n"
       ;;
esac
# if [ -e "/dev/shm/gemini.tmp" ]; then rm /dev/shm/gemini.tmp; fi