#!/bin/bash
#
# .---.                  .              .
# |                      |              |
# |--- .--. .-.  .-.  .-.|  .-. .--.--. |.-.  .-. .--.  .-.
# |    |   (.-' (.-' (   | (   )|  |  | |   )(   )|  | (.-'
# '    '     --'  --'  -' -  -' '  '   -' -'   -' '   -  --'
#
#                    Freedom in the Cloud
#
# Interactively creates a configuration file for use with the main
# freedombone command
#
# License
# =======
#
# Copyright (C) 2015-2017 Bob Mottram <bob@freedombone.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

NO_OF_ARGS=$#

PROJECT_NAME='freedombone'

# username created by default within a debian image
GENERIC_IMAGE_USERNAME='fbone'

export TEXTDOMAIN=${PROJECT_NAME}-config
export TEXTDOMAINDIR="/usr/share/locale"

# Web site
FREEDOMBONE_WEBSITE="https://freedombone.net or http://4fvfozz6g3zmvf76.onion"

# Minimum number of characters in a password
MINIMUM_PASSWORD_LENGTH=$(cat /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-passwords | grep 'MINIMUM_PASSWORD_LENGTH=' | head -n 1 | awk -F '=' '{print $2}')

# file containing new password
IMAGE_PASSWORD_FILE=/root/login.txt

MY_USERNAME=
DEFAULT_DOMAIN_NAME=
DEFAULT_DOMAIN_CODE=
MY_EMAIL_ADDRESS=
SYSTEM_TYPE='full'
INSTALLING_ON_BBB="no"
DDNS_PROVIDER=
DDNS_USERNAME=
DDNS_PASSWORD=
MY_NAME=
LOCAL_NETWORK_STATIC_IP_ADDRESS=
ROUTER_IP_ADDRESS=
ENABLE_BATMAN=
DEBIAN_REPO=
NAMESERVER1=
NAMESERVER2=
DOKUWIKI_TITLE=
DOKUWIKI_DOMAIN_NAME=
DOKUWIKI_CODE=
HTMLY_TITLE=
HTMLY_DOMAIN_NAME=
HTMLY_CODE=
HUBZILLA_DOMAIN_NAME=
HUBZILLA_CODE=
GNUSOCIAL_DOMAIN_NAME=
GNUSOCIAL_CODE=
GNUSOCIAL_WELCOME_MESSAGE=$"<h1>Welcome to \$GNUSOCIAL_DOMAIN_NAME – a federated social network</h1><p>Another $PROJECT_NAME site</p>"
GNUSOCIAL_BACKGROUND_IMAGE_URL=
GIT_DOMAIN_NAME=
GIT_CODE=
USB_DRIVE=/dev/sdb1
HWRNG_TYPE=
ENABLE_SOCIAL_KEY_MANAGEMENT=
WIFI_INTERFACE=wlan0
WIFI_TYPE='wpa2-psk'
WIFI_SSID=
WIFI_PASSPHRASE=
WIFI_HOTSPOT=
WIFI_NETWORKS_FILE=~/${PROJECT_NAME}-wifi.cfg
BATMAN_CELLID='any'
WIFI_CHANNEL=
CONFIGURATION_FILE=
DH_KEYLENGTH=
MINIMAL_INSTALL="yes"
DEFAULT_LANGUAGE='en_GB.UTF-8'
ONION_ONLY="no"
SELECTED_USERNAME=
SOCIALINSTANCE=

VALID_CODE=

PROJECT_INSTALL_DIR=/usr/local/bin
if [ -f /usr/bin/${PROJECT_NAME} ]; then
    PROJECT_INSTALL_DIR=/usr/bin
fi

function please_wait {
        local str width height length

        width=$(tput cols)
        height=$(tput lines)
        str=$"Please wait"
        length=${#str}
        clear
        tput cup $((height / 2)) $(((width / 2) - (length / 2)))
        echo "$str"
        tput cup $((height * 3 / 5)) $(((width / 2)))
        echo -n ''
}

source $PROJECT_INSTALL_DIR/${PROJECT_NAME}-vars

UTILS_FILES=/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-*
for f in $UTILS_FILES
do
    source $f
done

APP_FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*
for f in $APP_FILES
do
    source $f
done

function show_help {
    echo ''
    echo $"${PROJECT_NAME}-config -f [config filename] -m [min password length]"
    echo ''
    echo $'Creates an inventory of remote backup locations'
    echo ''
    echo ''
    echo $'  -h --help                         Show help'
    echo $'  -f --filename                     Configuration file (usually freedombone.cfg)'
    echo $'  -m --min                          Minimum password length (characters)'
    echo $'  -w --www                          Freedombone web site'
    echo $'  -b --bm                           Freedombone support Bitmessage address'
    echo $'  -o --onion [yes|no]               Whether to only create .onion sites'
    echo $'     --minimal [yes|no]             For minimalistic "consumer grade" installs'
    echo $'     --social [gnusocial|postactiv] Create gnusocial/postactiv instance'
    echo ''
    exit 0
}

function choose_email_address {
    if [[ $ONION_ONLY != "no" ]]; then
        EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
    else
        while [ ${#MY_EMAIL_ADDRESS} -lt 5 ]
        do
            EMAIL_ADDRESS=$(grep 'MY_EMAIL_ADDRESS' temp.cfg | awk -F '=' '{print $2}')
            if [ ! $EMAIL_ADDRESS ]; then
                EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
            fi
            if [ ${#MY_EMAIL_ADDRESS} -lt 5 ]; then
                EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME
            fi

            data=$(tempfile 2>/dev/null)
            trap "rm -f $data" 0 1 2 5 15
            dialog --backtitle $"Freedombone Configuration" \
                   --inputbox $"Your email address" 10 30 "$EMAIL_ADDRESS" 2> $data
            sel=$?
            case $sel in
                0) MY_EMAIL_ADDRESS=$(cat $data);;
                1) exit 1;;
                255) exit 1;;
            esac
        done
    fi
    save_configuration_values
}

function choose_social_instance_domain_name {
    DEFAULT_DOMAIN_DETAILS_COMPLETE=
    while [ ! $DEFAULT_DOMAIN_DETAILS_COMPLETE ]
    do
        data=$(tempfile 2>/dev/null)
        trap "rm -f $data" 0 1 2 5 15
        if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
            dialog --backtitle $"Freedombone Configuration" \
                   --title $"Instance domain" \
                   --form $"\nEnter your instance domain name and its FreeDNS code:" 11 55 3 \
                   $"Domain:" 1 1 "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 24 33 40 \
                   $"Code:" 2 1 "$(grep 'DEFAULT_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 24 33 255 \
                   2> $data
            sel=$?
            case $sel in
                1) exit 1;;
                255) exit 1;;
            esac
            DEFAULT_DOMAIN_NAME=$(cat $data | sed -n 1p)
            DEFAULT_DOMAIN_CODE=$(cat $data | sed -n 2p)
            if [ $DEFAULT_DOMAIN_NAME ]; then
                validate_freedns_code "$DEFAULT_DOMAIN_CODE"
                if [ ! $VALID_CODE ]; then
                    DEFAULT_DOMAIN_NAME=
                fi
            fi
        else
            dialog --backtitle $"Freedombone Configuration" \
                   --inputbox $"Enter your instance domain name:" 10 45 \
                   "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> $data
            sel=$?
            case $sel in
                0) DEFAULT_DOMAIN_NAME=$(cat $data);;
                1) exit 1;;
                255) exit 1;;
            esac
        fi
        if [ $DEFAULT_DOMAIN_NAME ]; then
            TEST_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME
            validate_domain_name
            if [[ $TEST_DOMAIN_NAME != $DEFAULT_DOMAIN_NAME ]]; then
                DEFAULT_DOMAIN_NAME=
                dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50
            else
                DEFAULT_DOMAIN_DETAILS_COMPLETE="yes"
            fi
        fi
    done
    save_configuration_values
}

function choose_default_domain_name {
    if [ $SOCIALINSTANCE ]; then
        choose_social_instance_domain_name
        return
    fi

    if [[ $ONION_ONLY != "no" ]]; then
        DEFAULT_DOMAIN_NAME="${LOCAL_NAME}.local"
    else
        DEFAULT_DOMAIN_DETAILS_COMPLETE=
        while [ ! $DEFAULT_DOMAIN_DETAILS_COMPLETE ]
        do
            data=$(tempfile 2>/dev/null)
            trap "rm -f $data" 0 1 2 5 15
            if [[ $DDNS_PROVIDER == "default@freedns.afraid.org" ]]; then
                dialog --backtitle $"Freedombone Configuration" \
                       --title $"Your main domain name" \
                       --form $"\nWhich domain name should your email/XMPP/IRC/Mumble be associated with?" 13 55 5 \
                       $"Domain:" 1 1 "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 24 33 40 \
                       $"Code:" 2 1 "$(grep 'DEFAULT_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 24 33 255 \
                       $"mail subdomain Code:" 3 1 "$(grep 'EMAIL_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 3 24 33 255 \
                       $"XMPP subdomain Code:" 4 1 "$(grep 'XMPP_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 4 24 33 255 \
                       2> $data
                sel=$?
                case $sel in
                    1) exit 1;;
                    255) exit 1;;
                esac
                DEFAULT_DOMAIN_NAME=$(cat $data | sed -n 1p)
                DEFAULT_DOMAIN_CODE=$(cat $data | sed -n 2p)
                EMAIL_DOMAIN_CODE=$(cat $data | sed -n 3p)
                XMPP_DOMAIN_CODE=$(cat $data | sed -n 4p)
                if [ $DEFAULT_DOMAIN_NAME ]; then
                    validate_freedns_code "$DEFAULT_DOMAIN_CODE"
                    if [ ! $VALID_CODE ]; then
                        DEFAULT_DOMAIN_NAME=
                    fi
                fi
                if [ $EMAIL_DOMAIN_CODE ]; then
                    validate_freedns_code "$EMAIL_DOMAIN_CODE"
                    if [ ! $VALID_CODE ]; then
                        DEFAULT_DOMAIN_NAME=
                        EMAIL_DOMAIN_CODE=
                    else
                        write_config_param "EMAIL_DOMAIN_CODE" "$EMAIL_DOMAIN_CODE"
                    fi
                fi
                if [ $XMPP_DOMAIN_CODE ]; then
                    validate_freedns_code "$XMPP_DOMAIN_CODE"
                    if [ ! $VALID_CODE ]; then
                        DEFAULT_DOMAIN_NAME=
                        XMPP_DOMAIN_CODE=
                    else
                        write_config_param "XMPP_DOMAIN_CODE" "$XMPP_DOMAIN_CODE"
                    fi
                fi
            else
                dialog --backtitle $"Freedombone Configuration" \
                       --inputbox $"Which domain name should your email/XMPP/IRC/Mumble be associated with?" 10 45 \
                       "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> $data
                sel=$?
                case $sel in
                    0) DEFAULT_DOMAIN_NAME=$(cat $data);;
                    1) exit 1;;
                    255) exit 1;;
                esac
            fi
            if [ $DEFAULT_DOMAIN_NAME ]; then
                TEST_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME
                validate_domain_name
                if [[ $TEST_DOMAIN_NAME != $DEFAULT_DOMAIN_NAME ]]; then
                    DEFAULT_DOMAIN_NAME=
                    dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50
                else
                    DEFAULT_DOMAIN_DETAILS_COMPLETE="yes"
                fi
            fi
        done
    fi
    save_configuration_values
}

function dynamic_dns_setup {
    data=$(tempfile 2>/dev/null)
    trap "rm -f $data" 0 1 2 5 15
    dialog --backtitle $"Freedombone Configuration" \
           --radiolist $"Choose Dynamic DNS provider:" 40 40 40 \
           1 dyn.com off \
           2 freedns.afraid.org on \
           3 zoneedit.com off \
           4 no-ip.com off \
           5 easydns.com off \
           6 tzo.com off \
           7 3322.org off \
           8 dnsomatic.com off \
           9 dns.he.net off \
           10 tunnelbroker.net off \
           11 dynsip.org off \
           12 sitelutions.com off \
           13 dnsexit.com off \
           14 changeip.com off \
           15 zerigo.com off \
           16 dhis.org off \
           17 nsupdate.info off \
           18 duckdns.org off \
           19 loopia.com off \
           20 namecheap.com off \
           21 domains.google.com off \
           22 ovh.com off \
           23 dtdns.com off \
           24 giradns.com off \
           25 duiadns.net off \
           26 ddnss.de off \
           27 dynv6.com off \
           28 ipv4.dynv6.com off \
           29 default@spdyn.de off \
           30 strato.com off \
           31 freemyip.com off \
           32 cloudxns.net off \
           33 none off 2> $data
    sel=$?
    case $sel in
        1) exit 1;;
        255) exit 1;;
    esac
    case $(cat $data) in
        1) DDNS_PROVIDER="default@www.dyn.com";;
        2) DDNS_PROVIDER="default@freedns.afraid.org";;
        3) DDNS_PROVIDER="default@www.zoneedit.com";;
        4) DDNS_PROVIDER="default@www.no-ip.com";;
        5) DDNS_PROVIDER="default@www.easydns.com";;
        6) DDNS_PROVIDER="default@www.tzo.com";;
        7) DDNS_PROVIDER="default@www.3322.org";;
        8) DDNS_PROVIDER="default@www.dnsomatic.com";;
        9) DDNS_PROVIDER="default@dns.he.net";;
        10) DDNS_PROVIDER="default@www.tunnelbroker.net";;
        11) DDNS_PROVIDER="default@www.dynsip.org";;
        12) DDNS_PROVIDER="default@www.sitelutions.com";;
        13) DDNS_PROVIDER="default@www.dnsexit.com";;
        14) DDNS_PROVIDER="default@www.changeip.com";;
        15) DDNS_PROVIDER="default@www.zerigo.com";;
        16) DDNS_PROVIDER="default@www.dhis.org";;
        17) DDNS_PROVIDER="default@nsupdate.info";;
        18) DDNS_PROVIDER="default@duckdns.org";;
        19) DDNS_PROVIDER="default@www.loopia.com";;
        20) DDNS_PROVIDER="default@www.namecheap.com";;
        21) DDNS_PROVIDER="default@domains.google.com";;
        22) DDNS_PROVIDER="default@www.ovh.com";;
        23) DDNS_PROVIDER="default@www.dtdns.com";;
        24) DDNS_PROVIDER="default@giradns.com";;
        25) DDNS_PROVIDER="default@www.duiadns.net";;
        26) DDNS_PROVIDER="default@ddnss.de";;
        27) DDNS_PROVIDER="default@dynv6.com";;
        28) DDNS_PROVIDER="default@ipv4.dynv6.com";;
        29) DDNS_PROVIDER="default@spdyn.de";;
        30) DDNS_PROVIDER="default@www.strato.com";;
        31) DDNS_PROVIDER="default@freemyip.com";;
        32) DDNS_PROVIDER="default@www.cloudxns.net";;
        33) DDNS_PROVIDER="none";;
        255) exit 1;;
    esac
    save_configuration_values

    valid_ddns_username=
    valid_ddns_password=
    if [[ "$DDNS_PROVIDER" == "none" ]]; then
        if [ -f /etc/systemd/system/inadyn.service ]; then
            systemctl stop inadyn
            systemctl disable inadyn
        fi
    else
        while [ ! $valid_ddns_username ]
        do
            data=$(tempfile 2>/dev/null)
            trap "rm -f $data" 0 1 2 5 15
            dialog --backtitle $"Freedombone Configuration" \
                   --inputbox $"Dynamic DNS provider username" 10 30 "$(grep 'DDNS_USERNAME' temp.cfg | awk -F '=' '{print $2}')" 2> $data
            sel=$?
            case $sel in
                0)  possible_username=$(cat $data)
                    if [ "$possible_username" ]; then
                        if [ ${#possible_username} -gt 1 ]; then
                            valid_ddns_username=$(cat $data)
                            DDNS_USERNAME=$valid_ddns_username
                            break;
                        fi
                    fi
                    ;;
                1) exit 1;;
                255) exit 1;;
            esac
        done
        save_configuration_values

        while [ ! $valid_ddns_password ]
        do
            data=$(tempfile 2>/dev/null)
            trap "rm -f $data" 0 1 2 5 15
            dialog --backtitle $"Freedombone Configuration" \
                   --clear \
                   --insecure \
                   --passwordbox $"Dynamic DNS provider password" 10 30 "$(grep 'DDNS_PASSWORD' temp.cfg | awk -F '=' '{print $2}')" 2> $data
            sel=$?
            case $sel in
                0)  possible_password=$(cat $data)
                    if [ "$possible_password" ]; then
                        if [ ${#possible_password} -gt 1 ]; then
                            valid_ddns_password=$(cat $data)
                            DDNS_PASSWORD=$valid_ddns_password
                            break;
                        fi
                    fi
                    ;;
                1) exit 1;;
                255) exit 1;;
            esac
            if [ ${#DDNS_PASSWORD} -lt $MINIMUM_PASSWORD_LENGTH ]; then
                dialog --title $"Password quality check" --msgbox $"The password given was too short. It must be at least $MINIMUM_PASSWORD_LENGTH characters. You may need to change your password on the dynamic DNS provider's web site." 10 40
                DDNS_PASSWORD=""
            fi
        done
        save_configuration_values
    fi
}

function choose_dynamic_dns {
    DDNS_PROVIDER="none"

    if [[ $SYSTEM_TYPE != "mesh"* && $ONION_ONLY == "no" ]]; then
        dialog --title $"Dynamic DNS" \
               --backtitle $"Freedombone Configuration" \
               --yesno $"\nConfigure a dynamic DNS service?\n\nIf it is already handled by your internet router then select 'no'." 10 50
        sel=$?
        case $sel in
            0) dynamic_dns_setup;;
            255) exit 1;;
        esac
    fi
    save_configuration_values
}

function choose_debian_repo {
    if [[ $MINIMAL_INSTALL == "no" ]]; then
        data=$(tempfile 2>/dev/null)
        trap "rm -f $data" 0 1 2 5 15
        dialog --backtitle $"Freedombone Configuration" \
               --radiolist $"Where to download Debian packages from:" 25 45 49 \
               1 $"Australia" off \
               2 $"Austria" off \
               3 $"Belarus" off \
               4 $"Belgium" off \
               5 $"Bosnia and Herzegovina" off \
               6 $"Brazil" off \
               7 $"Bulgaria" off \
               8 $"Canada" off \
               9 $"Chile" off \
               10 $"China" off \
               11 $"Croatia" off \
               12 $"Czech Republic" off \
               13 $"Denmark" off \
               14 $"El Salvador" off \
               15 $"Estonia" off \
               16 $"Finland" off \
               17 $"France 1" off \
               18 $"France 2" off \
               19 $"Germany 1" off \
               20 $"Germany 2" off \
               21 $"Greece" off \
               22 $"Hungary" off \
               23 $"Iceland" off \
               24 $"Iran" off \
               25 $"Ireland" off \
               26 $"Italy" off \
               27 $"Japan" off \
               28 $"Korea" off \
               29 $"Lithuania" off \
               30 $"Mexico" off \
               31 $"Netherlands" off \
               32 $"New Caledonia" off \
               33 $"New Zealand" off \
               34 $"Norway" off \
               35 $"Poland" off \
               36 $"Portugal" off \
               37 $"Romania" off \
               38 $"Russia" off \
               39 $"Slovakia" off \
               40 $"Slovenia" off \
               41 $"Spain" off \
               42 $"Sweden" off \
               43 $"Switzerland" off \
               44 $"Taiwan" off \
               45 $"Thailand" off \
               46 $"Turkey" off \
               47 $"Ukraine" off \
               48 $"United Kingdom" off \
               49 $"United States" on 2> $data
        sel=$?
        case $sel in
            1) exit 1;;
            255) exit 1;;
        esac
        case $(cat $data) in
            1) DEBIAN_REPO='ftp.au.debian.org';;
            2) DEBIAN_REPO='ftp.at.debian.org';;
            3) DEBIAN_REPO='ftp.by.debian.org';;
            4) DEBIAN_REPO='ftp.be.debian.org';;
            5) DEBIAN_REPO='ftp.ba.debian.org';;
            6) DEBIAN_REPO='ftp.br.debian.org';;
            7) DEBIAN_REPO='ftp.bg.debian.org';;
            8) DEBIAN_REPO='ftp.ca.debian.org';;
            9) DEBIAN_REPO='ftp.cl.debian.org';;
            10) DEBIAN_REPO='ftp.cn.debian.org';;
            11) DEBIAN_REPO='ftp.hr.debian.org';;
            12) DEBIAN_REPO='ftp.cz.debian.org';;
            13) DEBIAN_REPO='ftp.dk.debian.org';;
            14) DEBIAN_REPO='ftp.sv.debian.org';;
            15) DEBIAN_REPO='ftp.ee.debian.org';;
            16) DEBIAN_REPO='ftp.fi.debian.org';;
            17) DEBIAN_REPO='ftp2.fr.debian.org';;
            18) DEBIAN_REPO='ftp.fr.debian.org';;
            19) DEBIAN_REPO='ftp2.de.debian.org';;
            20) DEBIAN_REPO='ftp.de.debian.org';;
            21) DEBIAN_REPO='ftp.gr.debian.org';;
            22) DEBIAN_REPO='ftp.hu.debian.org';;
            23) DEBIAN_REPO='ftp.is.debian.org';;
            24) DEBIAN_REPO='ftp.ir.debian.org';;
            25) DEBIAN_REPO='ftp.ie.debian.org';;
            26) DEBIAN_REPO='ftp.it.debian.org';;
            27) DEBIAN_REPO='ftp.jp.debian.org';;
            28) DEBIAN_REPO='ftp.kr.debian.org';;
            29) DEBIAN_REPO='ftp.lt.debian.org';;
            30) DEBIAN_REPO='ftp.mx.debian.org';;
            31) DEBIAN_REPO='ftp.nl.debian.org';;
            32) DEBIAN_REPO='ftp.nc.debian.org';;
            33) DEBIAN_REPO='ftp.nz.debian.org';;
            34) DEBIAN_REPO='ftp.no.debian.org';;
            35) DEBIAN_REPO='ftp.pl.debian.org';;
            36) DEBIAN_REPO='ftp.pt.debian.org';;
            37) DEBIAN_REPO='ftp.ro.debian.org';;
            38) DEBIAN_REPO='ftp.ru.debian.org';;
            39) DEBIAN_REPO='ftp.sk.debian.org';;
            40) DEBIAN_REPO='ftp.si.debian.org';;
            41) DEBIAN_REPO='ftp.es.debian.org';;
            42) DEBIAN_REPO='ftp.se.debian.org';;
            43) DEBIAN_REPO='ftp.ch.debian.org';;
            44) DEBIAN_REPO='ftp.tw.debian.org';;
            45) DEBIAN_REPO='ftp.th.debian.org';;
            46) DEBIAN_REPO='ftp.tr.debian.org';;
            47) DEBIAN_REPO='ftp.ua.debian.org';;
            48) DEBIAN_REPO='ftp.uk.debian.org';;
            49) DEBIAN_REPO='ftp.us.debian.org';;
            255) exit 1;;
        esac
        save_configuration_values
    else
        DEBIAN_REPO='ftp.de.debian.org'
    fi
}

function choose_rng {
    if [[ $MINIMAL_INSTALL == "no" ]]; then
        data=$(tempfile 2>/dev/null)
        trap "rm -f $data" 0 1 2 5 15
        if [[ $INSTALLING_ON_BBB != "yes" ]]; then
            dialog --backtitle $"Freedombone Configuration" \
                   --radiolist $"Type of Random Number Generator:" 10 40 2 \
                   1 Haveged on \
                   2 OneRNG off 2> $data
            sel=$?
            case $sel in
                1) exit 1;;
                255) exit 1;;
            esac
            case $(cat $data) in
                2) HWRNG_TYPE="onerng"
                   dialog --title $"OneRNG Device" \
                          --msgbox $"Please ensure that the OneRNG device is disconnected. You can reconnect it later during the installation" 8 60
                   ;;
                255) exit 1;;
            esac
        else
            HWRNG_TYPE="beaglebone"
        fi
        save_configuration_values
    fi
}

function choose_social_key_management {
    if [[ $MINIMAL_INSTALL == "no" ]]; then
        interactive_gpg

        data=$(tempfile 2>/dev/null)
        trap "rm -f $data" 0 1 2 5 15
        SOCIAL_KEY_STR=$"\nDo you wish to enable social key management, otherwise known as \"the unforgettable key\"?\n\nThis means that fragments of your GPG key will be included with any remote backups so that if you later lose your key then it can be reconstructed from your friends servers. If you select \"no\" then you can still do social key management, but offline using physical USB thumb drives, which is more secure but less convenient."
        if [[ $(grep "ENABLE_SOCIAL_KEY_MANAGEMENT" temp.cfg | awk -F '=' '{print $2}') == "yes" ]]; then
            dialog --title $"Social Key Management" \
                   --backtitle $"Freedombone Configuration" \
                   --yesno "$SOCIAL_KEY_STR" 15 60
        else
            dialog --title $"Social Key Management" \
                   --backtitle $"Freedombone Configuration" \
                   --defaultno \
                   --yesno "$SOCIAL_KEY_STR" 15 60
        fi
        sel=$?
        case $sel in
            0) ENABLE_SOCIAL_KEY_MANAGEMENT="yes";;
            255) exit 1;;
        esac
        save_configuration_values
    else
        # enable for the minimal case
        ENABLE_SOCIAL_KEY_MANAGEMENT="yes"
    fi
}

function choose_username {
    if [ -d /home/$GENERIC_IMAGE_USERNAME ]; then
        if [ ! -f $IMAGE_PASSWORD_FILE ]; then
            echo 'Cannot find the password file for the admin user'
            exit 62753
        fi
        # when installing from an image which comes with a known default user account
        SELECTED_USERNAME=
        while [ ! $SELECTED_USERNAME ]
        do
            if [ ! $SELECTED_USERNAME ]; then
                SELECTED_USERNAME=$(grep 'MY_USERNAME' temp.cfg | awk -F '=' '{print $2}')
            fi
            data=$(tempfile 2>/dev/null)
            trap "rm -f $data" 0 1 2 5 15
            dialog --backtitle $"Freedombone Configuration" \
                   --title $"Username" \
                   --inputbox $"Set your username for the system\n\nYour username should not contain any spaces" 12 60 "$SELECTED_USERNAME" 2> $data
            sel=$?
            case $sel in
                0) possible_username=$(cat $data)
                   SELECTED_USERNAME=
                   if [[ $possible_username != *' '* && $possible_username != *'/'* && $possible_username != *'\'* && $possible_username != *'*'* ]]; then
                       if [ $possible_username ]; then
                           if [ ${#possible_username} -gt 1 ]; then
                               if [[ $possible_username != $GENERIC_IMAGE_USERNAME ]]; then
                                   MY_USERNAME=$(cat $data)
                                   please_wait
                                   echo ''
                                   echo $'Creating user account'
                                   chmod 600 /etc/shadow
                                   chmod 600 /etc/gshadow
                                   useradd -m -s /bin/bash $MY_USERNAME
                                   chmod 0000 /etc/shadow
                                   chmod 0000 /etc/gshadow
                                   if [ -d /home/$MY_USERNAME ]; then
                                       echo "${MY_USERNAME}:$(printf `cat $IMAGE_PASSWORD_FILE`)" | chpasswd
                                       # Add the user as a sudoer - they will be the new admin user
                                       if ! grep -q "$MY_USERNAME  ALL=(ALL) ALL" /etc/sudoers; then
                                           echo "$MY_USERNAME  ALL=(ALL) ALL" >> /etc/sudoers
                                           # remove the generic image admin user from sudoers
                                           sed -i "s|${GENERIC_IMAGE_USERNAME}.*||g" /etc/sudoers
                                       fi
                                       break
                                   fi
                               fi
                           fi
                       fi
                   fi
                   ;;
                1) exit 1;;
                255) exit 1;;
            esac
        done
    else
        no_of_users=$(find /home/* -maxdepth 0 -type d | wc -l)
        if [ $no_of_users -eq 1 ]; then
            # only a single user on the system
            MY_USERNAME=$(ls /home)
        else
            # select one from a number of users
            select_user
            if [ ! $SELECTED_USERNAME ]; then
                echo $'No username selected'
                exit 72589
            fi
            MY_USERNAME="$SELECTED_USERNAME"
        fi
    fi

    if [ ! $MY_USERNAME ]; then
        echo $'No user account was selected'
        exit 64398
    fi
    if [[ $MY_USERNAME == '-f' ]]; then
        echo $'No user account was selected'
        exit 8347
    fi
    if [[ $MY_USERNAME == 'debian' || $MY_USERNAME == 'fbone' ]]; then
        echo $"Don't use the default user account"
        exit 9341
    fi
    if [ ! -d /home/$MY_USERNAME ]; then
        echo $"The directory /home/$MY_USERNAME does not exist"
        exit 6437
    fi
    save_configuration_values
    please_wait
    echo ''
}

function choose_full_name {
    valid_name=
    while [ ! $valid_name ]
    do
        data=$(tempfile 2>/dev/null)
        trap "rm -f $data" 0 1 2 5 15
        dialog --backtitle $"Freedombone Configuration" \
               --inputbox $"Your full name (or nick)" 10 50 "$(grep 'MY_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> $data
        sel=$?
        case $sel in
            0)  possible_name=$(cat $data)
                if [ "$possible_name" ]; then
                    if [ ${#possible_name} -gt 1 ]; then
                        valid_name="$possible_name"
                        MY_NAME="$possible_name"
                        break;
                    fi
                fi
                ;;
            1) exit 1;;
            255) exit 1;;
        esac
    done
    save_configuration_values
    please_wait
    echo ''
}

function choose_system_variant {
    available_variants_list=()
    available_system_variants

    varslist=""
    n=1
    for a in "${available_variants_list[@]}"
    do
        varstate='off'
        if [[ "$a" == $'full' || "$a" == $'Full' ]]; then
            varstate='on'
        fi
        varslist="$varslist $n $a $varstate"
        n=$[n+1]
    done

    variant_choice=$(dialog --stdout --backtitle $"Freedombone Configuration" \
                            --title $"Type of Installation" \
                            --radiolist $'Choose:' \
                            27 40 20 $varslist)

    if [ $? -eq 0 ]; then
        variant_choice=$[variant_choice-1]
        SYSTEM_TYPE=${available_variants_list[$variant_choice]}
        save_configuration_values
    fi
}

function validate_freedns_code {
    freedns_code="$1"

    FREEDNS_MESSAGE=$"Please enter the FreeDNS code for this domain.\n\nThe code can be found by going to https://freedns.afraid.org, selecting 'Dynamic DNS' and then opening 'Wget example'. The code will consist of letters and numbers and be between the ? and = characters."

    if [[ "$freedns_code" == *"."* || "$freedns_code" == "http"* || "$freedns_code" == *"wget "* || "$freedns_code" == *" "* ]]; then
        dialog --title $"Invalid FreeDNS Code" --msgbox "$FREEDNS_MESSAGE" 10 70
        VALID_CODE=
    fi
    if [ ${#freedns_code} -lt 30 ]; then
        dialog --title $"Invalid FreeDNS Code" --msgbox $'FreeDNS code is too short. Did you enter the entire code?' 6 70
        VALID_CODE=
    fi
    VALID_CODE='yes'
}

# Get the commandline options
while [[ $# > 1 ]]
do
    key="$1"

    case $key in
        -h|--help)
            show_help
            ;;
        # Configuration filename
        -f|--filename)
            shift
            CONFIGURATION_FILE="$1"
            ;;
        # Minimum password length
        -m|--min)
            shift
            MINIMUM_PASSWORD_LENGTH="$1"
            ;;
        # Freedombone website
        -w|--www)
            shift
            FREEDOMBONE_WEBSITE="$1"
            ;;
        --social)
            shift
            if [[ "$1" == 'gnusocial' || "$1" == 'postactiv' ]]; then
                SOCIALINSTANCE="$1"
            fi
            ;;
        --minimal)
            shift
            MINIMAL_INSTALL="$1"
            ;;
        -o|--onion)
            shift
            ONION_ONLY="$1"
            ;;
        *)
            # unknown option
            ;;
    esac
    shift
done

function interactive_select_language {
    data=$(tempfile 2>/dev/null)
    trap "rm -f $data" 0 1 2 5 15
    dialog --backtitle $"Freedombone Configuration" \
           --radiolist $"Select your language:" 26 40 24 \
           1 $"Afrikaans" off \
           2 $"Albanian" off \
           3 $"Arabic" off \
           4 $"Basque" off \
           5 $"Belarusian" off \
           6 $"Bosnian" off \
           7 $"Bulgarian" off \
           8 $"Catalan" off \
           9 $"Croatian" off \
           10 $"Chinese (Simplified)" off \
           11 $"Chinese (Traditional)" off \
           12 $"Czech" off \
           13 $"Danish" off \
           14 $"Dutch" off \
           15 $"English" on \
           16 $"English (US)" off \
           17 $"Estonian" off \
           18 $"Farsi" off \
           19 $"Filipino" off \
           20 $"Finnish" off \
           21 $"French" off \
           22 $"French (Canada)" off \
           23 $"Gaelic" off \
           24 $"Gallego" off \
           25 $"Georgian" off \
           26 $"German" off \
           27 $"German (Personal)" off \
           28 $"Greek" off \
           29 $"Gujarati" off \
           30 $"Hebrew" off \
           31 $"Hindi" off \
           32 $"Hungarian" off \
           33 $"Icelandic" off \
           34 $"Indonesian" off \
           35 $"Italian" off \
           36 $"Japanese" off \
           37 $"Kannada" off \
           38 $"Khmer" off \
           39 $"Korean" off \
           40 $"Lao" off \
           41 $"Lithuanian" off \
           42 $"Latvian" off \
           43 $"Malayalam" off \
           44 $"Malaysian" off \
           45 $"Maori (Ngai Tahu)" off \
           46 $"Maori (Waikoto Uni)" off \
           47 $"Mongolian" off \
           48 $"Norwegian" off \
           49 $"Norwegian (Primary)" off \
           50 $"Nynorsk" off \
           51 $"Polish" off \
           52 $"Portuguese" off \
           53 $"Portuguese (Brazil)" off \
           54 $"Romanian" off \
           55 $"Russian" off \
           56 $"Samoan" off \
           57 $"Serbian" off \
           58 $"Slovak" off \
           59 $"Slovenian" off \
           60 $"Somali" off \
           61 $"Spanish (International)" off \
           62 $"Swedish" off \
           63 $"Tagalog" off \
           64 $"Tamil" off \
           65 $"Thai" off \
           66 $"Turkish" off \
           67 $"Ukrainian" off \
           68 $"Vietnamese" off 2> $data
    sel=$?
    case $sel in
        1) exit 1;;
        255) exit 1;;
    esac
    case $(cat $data) in
        1) DEFAULT_LANGUAGE='af_ZA.UTF-8';;
        2) DEFAULT_LANGUAGE='sq_AL.UTF-8';;
        3) DEFAULT_LANGUAGE='ar_SA.UTF-8';;
        4) DEFAULT_LANGUAGE='eu_ES.UTF-8';;
        5) DEFAULT_LANGUAGE='be_BY.UTF-8';;
        6) DEFAULT_LANGUAGE='bs_BA.UTF-8';;
        7) DEFAULT_LANGUAGE='bg_BG.UTF-8';;
        8) DEFAULT_LANGUAGE='ca_ES.UTF-8';;
        9) DEFAULT_LANGUAGE='hr_HR.UTF-8';;
        10) DEFAULT_LANGUAGE='zh_CN.UTF-8';;
        11) DEFAULT_LANGUAGE='zh_TW.UTF-8';;
        12) DEFAULT_LANGUAGE='cs_CZ.UTF-8';;
        13) DEFAULT_LANGUAGE='da_DK.UTF-8';;
        14) DEFAULT_LANGUAGE='nl_NL.UTF-8';;
        15) DEFAULT_LANGUAGE='en_GB.UTF-8';;
        16) DEFAULT_LANGUAGE='en_US.UTF-8';;
        17) DEFAULT_LANGUAGE='et_EE.UTF-8';;
        18) DEFAULT_LANGUAGE='fa_IR.UTF-8';;
        19) DEFAULT_LANGUAGE='ph_PH.UTF-8';;
        20) DEFAULT_LANGUAGE='fi_FI.UTF-8';;
        21) DEFAULT_LANGUAGE='fr_FR.UTF-8';;
        22) DEFAULT_LANGUAGE='fr_CA.UTF-8';;
        23) DEFAULT_LANGUAGE='ga.UTF-8';;
        24) DEFAULT_LANGUAGE='l_ES.UTF-8';;
        25) DEFAULT_LANGUAGE='ka_GE.UTF-8';;
        26) DEFAULT_LANGUAGE='de_DE.UTF-8';;
        27) DEFAULT_LANGUAGE='de_DE.UTF-8';;
        28) DEFAULT_LANGUAGE='el_GR.UTF-8';;
        29) DEFAULT_LANGUAGE='gu.UTF-8';;
        30) DEFAULT_LANGUAGE='he_IL.utf8';;
        31) DEFAULT_LANGUAGE='hi_IN.UTF-8';;
        32) DEFAULT_LANGUAGE='hu.UTF-8';;
        33) DEFAULT_LANGUAGE='is_IS.UTF-8';;
        34) DEFAULT_LANGUAGE='id_ID.UTF-8';;
        35) DEFAULT_LANGUAGE='it_IT.UTF-8';;
        36) DEFAULT_LANGUAGE='ja_JP.UTF-8';;
        37) DEFAULT_LANGUAGE='kn_IN.UTF-8';;
        38) DEFAULT_LANGUAGE='km_KH.UTF-8';;
        39) DEFAULT_LANGUAGE='ko_KR.UTF-8';;
        40) DEFAULT_LANGUAGE='lo_LA.UTF-8';;
        41) DEFAULT_LANGUAGE='lt_LT.UTF-8';;
        42) DEFAULT_LANGUAGE='lat.UTF-8';;
        43) DEFAULT_LANGUAGE='ml_IN.UTF-8';;
        44) DEFAULT_LANGUAGE='ms_MY.UTF-8';;
        45) DEFAULT_LANGUAGE='mi_NZ.UTF-8';;
        46) DEFAULT_LANGUAGE='mi_NZ.UTF-8';;
        47) DEFAULT_LANGUAGE='mn.UTF-8';;
        48) DEFAULT_LANGUAGE='no_NO.UTF-8';;
        49) DEFAULT_LANGUAGE='no_NO.UTF-8';;
        50) DEFAULT_LANGUAGE='nn_NO.UTF-8';;
        51) DEFAULT_LANGUAGE='pl.UTF-8';;
        52) DEFAULT_LANGUAGE='pt_PT.UTF-8';;
        53) DEFAULT_LANGUAGE='pt_BR.UTF-8';;
        54) DEFAULT_LANGUAGE='ro_RO.UTF-8';;
        55) DEFAULT_LANGUAGE='ru_RU.UTF-8';;
        56) DEFAULT_LANGUAGE='mi_NZ.UTF-8';;
        57) DEFAULT_LANGUAGE='sr_CS.UTF-8';;
        58) DEFAULT_LANGUAGE='sk_SK.UTF-8';;
        59) DEFAULT_LANGUAGE='sl_SI.UTF-8';;
        60) DEFAULT_LANGUAGE='so_SO.UTF-8';;
        61) DEFAULT_LANGUAGE='es_ES.UTF-8';;
        62) DEFAULT_LANGUAGE='sv_SE.UTF-8';;
        63) DEFAULT_LANGUAGE='tl.UTF-8';;
        64) DEFAULT_LANGUAGE='ta_IN.UTF-8';;
        65) DEFAULT_LANGUAGE='th_TH.UTF-8';;
        66) DEFAULT_LANGUAGE='tr_TR.UTF-8';;
        67) DEFAULT_LANGUAGE='uk_UA.UTF-8';;
        68) DEFAULT_LANGUAGE='vi_VN.UTF-8';;
    esac
    save_configuration_values

    please_wait
    echo ''
    echo 'Setting locale'

    locale-gen "${DEFAULT_LANGUAGE}"
    update-locale LANG=${DEFAULT_LANGUAGE}
    update-locale LANGUAGE=${DEFAULT_LANGUAGE}
    update-locale LC_MESSAGES=${DEFAULT_LANGUAGE}
    update-locale LC_ALL=${DEFAULT_LANGUAGE}
    update-locale LC_CTYPE=${DEFAULT_LANGUAGE}
    please_wait
    echo ''
}

function select_user {
    SELECTED_USERNAME=

    users_array=($(ls /home))

    delete=(git)
    for del in ${delete[@]}
    do
        users_array=(${users_array[@]/$del})
    done

    i=0
    W=()
    name=()
    for u in ${users_array[@]}
    do
        if [[ $(is_valid_user "$u") == "1" ]]; then
            i=$((i+1))
            W+=($i "$u")
            name+=("$u")
        fi
    done

    if [ $i -eq 1 ]; then
        SELECTED_USERNAME="${name[0]}"
    else
        user_index=$(dialog --backtitle $"Freedombone Configuration" --title $"Select User" --menu $"Select one of the following:" 24 40 17 "${W[@]}" 3>&2 2>&1 1>&3)

        if [ $? -eq 0 ]; then
            SELECTED_USERNAME="${name[$((user_index-1))]}"
        fi
    fi
}

function interactive_config {
    # create a temporary copy of the configuration file
    # which can be used to pre-populate selections
    if [ -f $CONFIGURATION_FILE ]; then
        cp $CONFIGURATION_FILE temp.cfg
    fi

    interactive_select_language

    if [ $SOCIALINSTANCE ]; then
        INITIAL_MESSAGE=$"Welcome to your Freedombone $SOCIALINSTANCE instance.\n\nEnsure that you have your domain and dynamic DNS settings ready.\n\nFor more information please visit ${FREEDOMBONE_WEBSITE}/socialinstance.html."
    else
        if [[ $ONION_ONLY == "no" ]]; then
            INITIAL_MESSAGE=$"Welcome to the Freedombone interactive installer. Communications freedom is only a short time away.\n\nEnsure that you have your domain and dynamic DNS settings ready.\n\nFor more information please visit $FREEDOMBONE_WEBSITE."
        else
            INITIAL_MESSAGE=$"Welcome to the Freedombone interactive installer. Communications freedom is only a short time away.\n\nWeb sites created will only be viewable within a Tor browser.\n\nFor more information please visit $FREEDOMBONE_WEBSITE."
        fi
    fi

    dialog --title $"Freedombone" --msgbox "$INITIAL_MESSAGE" 15 50

    #choose_system_variant
    choose_username
    choose_full_name
    choose_social_key_management
    choose_rng
    choose_debian_repo
    ${PROJECT_NAME}-wifi --networksinteractive $WIFI_NETWORKS_FILE
    choose_dynamic_dns
    choose_default_domain_name
    choose_email_address
    interactive_key_recovery

    if [[ "$SOCIALINSTANCE" == 'gnusocial' ]]; then
        GNUSOCIAL_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME
        GNUSOCIAL_CODE=$DEFAULT_DOMAIN_CODE
        write_config_param "GNUSOCIAL_DOMAIN_NAME" "$GNUSOCIAL_DOMAIN_NAME"
        write_config_param "GNUSOCIAL_CODE" "$GNUSOCIAL_CODE"
        write_config_param "SOCIALINSTANCE" "$SOCIALINSTANCE"
        install_gnusocial
    fi

    if [[ "$SOCIALINSTANCE" == 'postactiv' ]]; then
        POSTACTIV_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME
        POSTACTIV_CODE=$DEFAULT_DOMAIN_CODE
        write_config_param "POSTACTIV_DOMAIN_NAME" "$POSTACTIV_DOMAIN_NAME"
        write_config_param "POSTACTIV_CODE" "$POSTACTIV_CODE"
        write_config_param "SOCIALINSTANCE" "$SOCIALINSTANCE"
        install_postactiv
    fi

    # delete the temporary configuration file
    if [ -f temp.cfg ]; then
        shred -zu temp.cfg
    fi

    # This file indicates that the configuration happened successfully
    touch $HOME/.${PROJECT_NAME}-interactive
}

function show_result {
    #clear
    echo ''
    echo -n $"Configuration filename:"
    echo " $CONFIGURATION_FILE"
    echo ''
    echo $'Contents:'
    echo ''
    cat $CONFIGURATION_FILE
    echo ''
}

if [ ! $CONFIGURATION_FILE ]; then
    CONFIGURATION_FILE=$HOME/${PROJECT_NAME}.cfg
fi

read_configuration_values
interactive_config
#show_result

exit 0
