#!/bin/sh
set -e

. /usr/share/debconf/confmodule

db_capb backup

INDENT="  "

localecode="debian-installer/locale"
fallbacklocalecode="debian-installer/fallbacklocale"
languagechooserlocalecode="languagechooser/locale"
languagecode="debian-installer/language"
countrycode="debian-installer/country"
languagechooserlanguage="languagechooser/language-name"
shortlist="countrychooser/shortlist"
fulllist="countrychooser/country-name"

# This is the iso_3166.tab file location
ISO3166TAB=/usr/share/iso-codes/iso_3166.tab
SUPPORTEDLOCALES=/etc/SUPPORTED-short
SHORTLISTS=/etc/shortlists

for list in $ISO3166TAB ; do 
	if [ -f "$list" ]; then
		countries="$list"
	fi
done

error() {
	logger -t countrychooser "error: $@"
	exit 1
}

log() {
	logger -t countrychooser "info: $@"
}

code2country() {
	COUNTRYCODE="$1"
	line=`grep "$COUNTRYCODE" $countries`

	if [ -n "$line" ]; then
		# Remember that country names may have spaces so the code
		# is different than in country2code.
		printf "$INDENT"
		echo $line | cut -b 4-
	else
		error "Unable to locate info on country '$COUNTRYCODE'"
	fi
}

country2code() {
	COUNTRYNAME=$(echo "$1" | sed "s/^$INDENT//" | sed 's/\\,/,/g')
	line=`grep "$COUNTRYNAME$" $countries`

	if [ -n "$line" ]; then
		set $line
		if [ -n "$1" ]; then
			echo "$1"
		fi
	fi
}

# First grab back the country we got from languagechooser
# (or from elsewhere) and populate the debconf database with
# it so that it becomes the default choice
db_get "$countrycode"
if [ -n "$RET" ]; then
	# Remember which code was first used
	# This is needed at the end of the script
	COUNTRYCODE_LANGUAGECHOOSER="$RET"
	COUNTRY_LANGUAGECHOOSER="$(code2country "$RET")"
	db_fget "$fulllist" seen
	if [ "$RET" = false ]; then
		db_set "$fulllist" "${COUNTRY_LANGUAGECHOOSER}"
	fi
fi


# Then grab back the language we got from languagechooser
db_get "$languagechooserlanguage"
if [ -n "$RET" ]; then
	LANGNAME="$RET"
	# languagemap is a script from languagechooser which
	# returns the language list in LANGUAGELIST and the
	# language alone in LANGUAGE
	if ! . languagemap ; then
		LANGUAGE=C
        else
		# We need to remember these for further use
	        LOCALE_LANGUAGECHOOSER=$LOCALE
		LANGUAGECODE_LANGUAGECHOOSER=$LANGUAGE
	fi
fi

# Then grab back the locale we got from languagechooser
db_get "$localecode"
if [ -n "$RET" ]; then
	DEFAULTLOCALE="$RET"
else
	# Just in case
	DEFAULTLOCALE="C"
fi

# Finally grab the fallback locale we got from languagechooser
db_get "$fallbacklocalecode"
if [ -n "$RET" ]; then
	FALLBACKLOCALE="$RET"
else
	# Just in case
	FALLBACKLOCALE="C"
fi

log "LANGUAGECODE_LANGUAGECHOOSER = '$LANGUAGECODE_LANGUAGECHOOSER'"
log "COUNTRYCODE_LANGUAGECHOOSER = '$COUNTRYCODE_LANGUAGECHOOSER'"
log "LOCALE_LANGUAGECHOOSER = '$LOCALE_LANGUAGECHOOSER'"
log "FALLBACKLOCALE = '$FALLBACKLOCALE'"

# If present, keep track of charset or modifier we got from languagechooser
# This charset or modifier is in the fallback locale
EXTRA_LANGUAGECHOOSER=`echo $FALLBACKLOCALE | sed -e 's/^[^.@]*//'`


FIRST_LANG=$(echo $LANGUAGELIST | sed -e 's/:.*$//')

# We use /etc/shortlists to check if we should present a shortlist
if grep -q "^$FIRST_LANG" $SHORTLISTS; then
  use_lang=$FIRST_LANG
elif grep -q "^$LANGUAGE" $SHORTLISTS; then
  use_lang=$LANGUAGE
else
  use_lang=""
fi

# At this step we should have either xx, or xx_YY in LANGNAME
if [ "$LANGUAGE" != "C" ]; then
	STATE=1
	LASTSTATE=3
	fullprio=high
	shortprio=high
	while [ "$STATE" != 0 -a "$STATE" -le "$LASTSTATE" ]; do
		case "$STATE" in
		1)
			# If the locale includes a country, then
			# don't display the short list, and only show the
			# full list at medium priority.
			askedshort=0
			if (echo $DEFAULTLOCALE | grep "_" >/dev/null 2>&1) ; then
				fullprio=medium
			else
				if [ "$use_lang" ]; then
                                        shortlist_template="$shortlist-$use_lang"
                                        db_register $shortlist_template $shortlist
                                        # Set the default
					db_fget $shortlist seen
					if [ "$RET" = false ]; then
	                                        db_set $shortlist $COUNTRYCODE_LANGUAGECHOOSER
					fi
                                        db_input $shortprio $shortlist || [ $? -eq 30 ]
					askedshort=1
				fi
			fi
		;;
		2)
			if [ "$askedshort" = 1 ] ; then
				db_get $shortlist
				if [ -n "$RET" ] && [ "$RET" != "other" ]; then
					COUNTRYCODE="$RET"
					break
				fi
			fi
			
			db_input $fullprio $fulllist || [ $? -eq 30 ]
		;;
		3)
			db_get $fulllist
			COUNTRYCODE="$(country2code "$RET")" || true
			if [ -n "$COUNTRYCODE" ]; then
				break
			else
				# User probably selected a region.
				STATE=2
				continue
			fi
		;;
		esac

		if db_go; then
			STATE=$(($STATE + 1))
		else
			STATE=$(($STATE - 1))
		fi
	done

	if [ "$STATE" = 0 ]; then
		exit 10 # back out to main menu
	fi
fi

db_set "$countrycode"  "$COUNTRYCODE"
log "Set $countrycode = '$COUNTRYCODE'"

# Search for a supported locale which most closely resembles.
LOCALE=""
log "LANGUAGE = '$LANGUAGE'"
log "COUNTRYCODE = '$COUNTRYCODE'"

for entry in ${LANGUAGE}_${COUNTRYCODE}${EXTRA_LANGUAGECHOOSER} \
	     ${LANGUAGE}_${COUNTRYCODE}; do
	# Is the locale we inherited from languagechooser
	# really a complete locale?
        LOCALE_LANGUAGECHOOSER_COMPLETE=$(echo ${LOCALE_LANGUAGECHOOSER} | grep "_" || true)
	if grep -q "^${entry}$" $SUPPORTEDLOCALES; then
		# Special handling of cases where the locale
		# in languagechooser is NOT the combination of
		# language_COUNTRY. Used for Norwegian Bokmal transition
		# in order to keep no_NO as locale. May be used in the
		# future for other special cases, so we'd better keep this
	        if \
		    [ "${LANGUAGE}" = "${LANGUAGECODE_LANGUAGECHOOSER}" \
		      -a \
		      "${COUNTRYCODE}" = "${COUNTRYCODE_LANGUAGECHOOSER}" \
		      -a \
		      "${LANGUAGE}_${COUNTRYCODE}" != "${LOCALE_LANGUAGECHOOSER}" \
		      -a \
		      -n "${LOCALE_LANGUAGECHOOSER_COMPLETE}" \
		    ] ;  then
		    # In details : we revert back to the locale
		    # defined in languagechooser if countrychooser
		    # did NOT induce change in language and country
		    # but the resulting locale is different from the
		    # one we had in languagechooser
		    LOCALE=${LOCALE_LANGUAGECHOOSER}
		else
		    LOCALE="${entry}"
		fi
		break
	fi
done

# Fall back to a supported locale.
if [ -z "${LOCALE}" ]; then
        if grep -q "^${FALLBACKLOCALE}$" $SUPPORTEDLOCALES; then
                LOCALE="${FALLBACKLOCALE}"
        else
                LOCALE=`echo $FALLBACKLOCALE | sed -e 's/[.@].*$//'`
        fi
        log "Falling back to locale '${LOCALE}'"
fi

# Set the locale.
db_set "$localecode" "${LOCALE}"
log "Set $localecode = '${LOCALE}'"

# The code below tries to add lang_COUNTRY at the beginning of the language
# list we got from languagechooser
# Example:
#   -user chooses "Arabic" at languagechooser-->she gets "ar_EG:ar:en_US:en"
#    (see the languagelist file from languagechooser)
#   -she chooses "Syria" as country-->then we end up with 
#    "ar_SY:ar_EG:ar:en_UC:en"
# We shouldn't just add this before the former list in case the country 
# is changed several times.
if [ "$COUNTRYCODE" != "$COUNTRYCODE_LANGUAGECHOOSER" -a -n "$COUNTRYCODE" -a -n "$LANGUAGE" ]; then
	LANGUAGELIST=${LANGUAGE}_${COUNTRYCODE}:${LANGUAGELIST}
	# Languagelist setting
	db_set "$languagecode" "$LANGUAGELIST"
	log "Set $languagecode = '$LANGUAGELIST'"
fi

exit 0
