#!/bin/sh
# 2004-2010 (c) Etersoft www.etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>
# Public domain
#
# Скачивает исходный src.rpm-пакет с одного из репозиториев (по умолчанию ALT Linux) для пакета с указанным названием.
# Также можно сразу указать название пакета с исходниками
# Функции скрипта похожи на команду apt-get source пакет
# -c - checkonline

# load common functions, compatible with local and installed script
. `dirname $0`/../share/eterbuild/functions/common
load_mod rpm repl git rpm web repos

# loads repos file and fill SYSNAME and SYSURL arrays
load_systems_list()
{
	local IDX=0
	local line
	while read line ; do
		# skip comments
		echo $line | grep "^#" >/dev/null && continue
		SYSNAME[$IDX]=${line/ *.*/}
		#FTP[$IDX]=${line/.* \+/}
		SYSURL[$IDX]=$(echo $line | sed -e "s|.* \+||g")
		IDX=$(($IDX+1))
	done < $ETERBUILDETC/repos/srpms
}

list_systems()
{
	echo "Known systems:"
	for ((i=0; i < ${#SYSNAME[*]}; i++)) ; do
			printf "[%-17s] %s\n" ${SYSNAME[$i]} ${SYSURL[$i]}
	done
	echo
	echo "You can add system to /etc/eterbuild/repos/srpms"
}

html_filter()
{
	grep "src.rpm" | sed -e "s|.*href=\"||g" | sed -e "s|\".*||g"
}

list_filter()
{
	sed -e "s|.src.rpm$||g"
}

# Using: git_list idx [force]
# set LIST variable to list file
get_list()
{
	[ -n "$VERBOSE" ] && echo "get_list for $1"
	local URL=${SYSURL[$1]}
	local FORCE=$2
	local SYS=${SYSNAME[$1]}
	local CURL=curl

	which $CURL 2>/dev/null >/dev/null || fatal "curl command needed for download"
	LIST=$OURTMPDIR/tmp-rpmgpall-$SYS
	if [ ! -f "$LIST" ] || [ "$FORCE" = "force" ] ; then
		echo "Get list for $SYS from $URL"
		#curl -l $URL/ >$LIST
		# suitable for ftp and http lists
		$CURL -l $URL/ | html_filter >$LIST
	else
		echo "List for $SYS"
	fi
}

get_system_idx()
{
	if [ -z "$1" ] ; then
		return 1
	fi
	for ((i=0; i < ${#SYSNAME[*]}; i++)) ; do
		if [ ${SYSNAME[$i]} = "$1" ] ; then
			echo $i
			return 0
		fi
	done
	return 1
}

check_name()
{
	if [ -z "$1" ] ; then
		return
		#echo "Error: missed package param"
		#exit 1
	fi
	NLIST=`cat $LIST | grep -i "$1"`
#	if [ `cat $LIST | list_filter | grep -i $1 | wc -l` -gt 1 ] ; then
		#echo "Please type a full name of the package"
#		print_list $NLIST
#		return 1
#	fi

	if [ -z "$NLIST" ] ; then
		echo "$1: Not found"
		return 1
	fi

	return 0
}

check_system()
{
	local i
	local IDX=$1
	local URL=${SYSURL[$IDX]}
	#echo "Check for $SYSTEM"
	get_list $IDX
	#ls -l $LIST
	check_name $PKGNAME
	if [ "$DOWNLOADALL" ] ; then
		for i in $NLIST ; do
			download_url $URL/$i
		done
	fi
}

update_cache_list()
{
	load_systems_list
	# if followed by system name
	IDX=`get_system_idx "$1"`
	if [ -n "$IDX" ] ; then
		get_list $IDX force
		shift
		exit 0
	fi
	# update all systems
	for ((i=0; i < ${#SYSNAME[*]}; i++)) ; do
		get_list $i force
	done
}

Usage="Usage: rpmgp [options] [-$CURRENTBRANCHNAME] [system] pkgname"
mygetopts()
{
Descr="rpmgp - various package download operations"

phelp()
{
# TODO: improve description
	echog "$Descr"
	echog "$Usage"
	echog "Options:"
	echog " pkgname - installed package name or src.rpm"
	echog " system - name of system (ALT Linux by default if -a missed)"
	echog " -a  search pkgname in all known repositories"
	echog " -c  check if this package exists in the ALT Linux repository"
	echog " -d  download all matched packages"
	echog " -g  clone last built package repo"
	echog " -gp  clone last built package repo via public access"
	echog " -gm remote clone repo to USER/packages and clone it locally"
	echog " -m  migrate to gear from spec/srpm"
	echog "Ext. options:"
	echog " -b  install packages needed for build (use sudo apt-get) (need spec not package name)"
	echog " -l  list packages needed for build (in local pkg system notation) (experimental)"
	echog " -r  refresh package list (download it again)"
	echog " -s  list all known remote repositories"
	exit 0
}

while getopts :habcdglmprs opt; do
    case $opt in
    h) phelp; exit 0;;
    a) ALLSYSTEM=1 ;;
    b) INSTALLBINARY=1 ;;
    c) CHECKONLINE=1 ;;
    d) DOWNLOADALL=1 ;;
    g) CLONEGIT=1 ;;
    l) LISTREQS=1 ;;
    m) MIGRATEGIRAR=1 ;;
    p) PUBLICACCESS=1 ;;
    r) UPDATECACHE=1 ;;
    s) load_systems_list
       list_systems
       exit 0
       ;;
    +?) echog "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
#    ?)  echog "$name: $OPTARG: bad option.  Use -h for help." 1>&2 ; exit 2;;
    ?) OPTIND=$((OPTIND-1)); break;
    esac
done

# FIXME: параметры передаются и дальше (например, -i, -b)
# remove args that were options
#if [ $# -gt 0 ]; then 
#	shift $((OPTIND - 1))
#fi
# remove args that were options
shift $((OPTIND - 1))


# pass other options to RPM:
LISTRPMARGS=$@
}

set_girar_host $1 && shift

parse_cmd_pre "$@"
mygetopts $LISTARGS

# optional arg
if [ -n "$UPDATECACHE" ] ; then
    update_cache_list $1
    exit 0
fi

PKGNAME=$(strip_spaces $LISTRPMARGS $LISTNAMES)

if [ -z "$ALLSYSTEM$UPDATECACHE" ] ; then
	test -z "$PKGNAME" && fatal "Please run with spec/package name"
fi

# список названий систем, адресов (с зеркалами?), и режимов фильтрации
# название кэш-файла строить из названия системы
# выводить найденное сразу везде
#
# уточнение - [система] пакет

# install required for build binary packages
if [ -n "$INSTALLBINARY" ] ; then
    # pack by LISTNAMES list
    pack_src_rpm --commit $LISTRPMARGS
    LISTPKG=$(rpmquery --requires -p $LISTBUILT | clean_pkgreq | sed -e "s|rpm-build-altlinux-compat||g")
    CMD=$(get_install_package_command `$DISTRVENDOR -d` interactive)
    echog "Running $SUDO $CMD $LISTPKG"
    exec $SUDO $CMD $LISTPKG
fi

# TODO: do gpull -a for get all branches?
get_all_remote_branches()
{
	local CURRENTBRANCH=$(get_current_branch)
	# create all branches
	for i in $(git branch -a | grep -v "/HEAD" | grep "remotes/origin/") ; do
		local BRANCHNAME=$(echo $i | sed -e "s|remotes.*/||g")
		if is_exist_branch $BRANCHNAME ; then
			git checkout $BRANCHNAME || fatal "can't checkout $BRANCHNAME"
			git pull origin $BRANCHNAME
		else
			git checkout -b $(echo $i | sed -e "s|remotes.*/||g") $i
		fi
	done
	git checkout sisyphus || git checkout master || git checkout $CURRENTBRANCH
}

git_clone()
{
	local RREPO="$1"
	# Test if ssh access is available
	if [ -z "$PUBLICACCESS" ] && ssh $GIRARHOST help >/dev/null 2>&1 ; then
		echo "Clone from $GIRARHOST:$RREPO ..."
		git clone $GIRARHOST:$RREPO
	else
		echo "Clone from $GIRARURL/$RREPO ..."
		git clone $GIRARURL/$RREPO
	fi
}

# clone remote git
if [ -n "$CLONEGIT" ] ; then
	# http://git.altlinux.org/gears/N/NAME.git
	REPOPATH="$(initial_letter $PKGNAME)/$PKGNAME.git"
	RREPO="/gears/$REPOPATH"

	if [ -z "$MIGRATEGIRAR" ] ; then
		if ! git_clone $RREPO; then
			# http://git.altlinux.org/srpms/N/NAME.git
			RREPO="/srpms/$REPOPATH"
			git_clone $RREPO || fatal "Can't clone $RREPO."
		fi
	else
		[ -z "$PUBLICACCESS" ] || fatal "Can't remote clone via public access"
		echo "Remote clone from $RREPO ..."
		if ! ssh $GIRARHOST clone $RREPO packages/$PKGNAME.git ; then
			# http://git.altlinux.org/srpms/N/NAME.git
			RREPO="/srpms/$REPOPATH"
			echo "Remote clone from $RREPO ..."
			ssh $GIRARHOST clone $RREPO packages/$PKGNAME.git || warning "Can't remote clone."
		fi

		git clone $GIRARHOST:packages/$PKGNAME.git
	fi

	# get or update all branches
	if cd $PKGNAME ; then
		get_all_remote_branches
		cd - >/dev/null
	fi

	echo "See other repos at $GIRARHOST:"
	list_git_package $PKGNAME
	exit $?
fi

if [ -n "$MIGRATEGIRAR" ] ; then
	for INFILE in $LISTNAMES ; do
		# call for each file due generated BASENAME
		LISTNAMES=$INFILE pack_src_rpm $INFILE $LISTRPMARGS
		PKGNAME="$LISTBUILT"
		if [ -z "$BASENAME" ] ; then
			echo "Can't get basename for $PKGNAME, skipping"
			continue
		fi
		echo "Create gear repo $BASENAME from $PKGNAME in $GITREPODIR"
		[ -n "$GITREPODIR" ] || GITREPODIR=$(pwd)
		GEARDIR=$GITREPODIR/$BASENAME
		test -d "$GEARDIR" && fatal "repo $GEARDIR already exits"
		mkdir -p "$GEARDIR" || fatal "can't create dir $GEARDIR"
		cd $GEARDIR || fatal "can't cd to $GEARDIR"
		git init-db || fatal "can't init db"
		gear-srpmimport $PKGNAME || fatal "can't import srpm $PKGNAME"
		# remove src.rpm only if it was generated from spec
		[ -z ${INFILE/*rpm/} ] || rm -vf $PKGNAME
		rpmcs
	done
	exit 0
fi

# lists packages for build
if [ -n "$LISTREQS" ] ; then
	print_target_buildreq $PKGNAME
	exit $?
fi

# Check online
if [ -n "$CHECKONLINE" ] ; then

	# possible it is spec
	if [ -f "$PKGNAME" ] ; then
		build_rpms_name "$PKGNAME"
		SRCRPM=$NAMESRPMIN
		PKGNAME=$(get_pkgname_from_filename $SRCRPM)
	else
		if echo $PKGNAME | grep -q "\.rpm" ; then
			# possible it is rpm package name
			SRCRPM=$PKGNAME
			PKGNAME=$(get_pkgname_from_filename $SRCRPM)
		else
			SRCRPM=$(querypackage $PKGNAME "" "%{SOURCERPM}\n" | tail -n 1)
		fi
	fi

	if [ -n "$GIRAR_USER" ] ; then
		GITURL="http://git.altlinux.org/people/$GIRAR_USER/packages/$PKGNAME.git"
		if $GET -d $GITURL ; then
			echog "Published at $GITURL by $GIRAR_USER"
		else
			echog "There is no git repo $GITURL"
		fi
	fi
	echo "Get repositories at $GIRARHOST:"
	list_git_package $PKGNAME

	set_binaryrepo $MENV
	echo -n "ACL list for $GIRARHOST $BINARYREPO: "
	ssh $GIRARHOST acl $BINARYREPO $PKGNAME show
	RET="MISSED"
	if [ -n "$SRCRPM" ] ; then
		RSYNCPATH=$(get_rsync_path $GIRARHOST $BINARYREPO)
		echog "Checking '$PKGNAME' in '$RSYNCPATH' ..."
		if $RSYNC -n $RSYNCPATH/files/SRPMS/$SRCRPM 2>/dev/null | grep $PKGNAME ; then
			RET=OK
			echo "Package $SRCRPM is the latest version from $RSYNCPATH"
		else
			# upstream version difference, just printout list
			RSYNCPATH=$(get_rsync_path $GIRARHOST $BINARYREPO)
			$RSYNC -n "$RSYNCPATH/files/SRPMS/$PKGNAME-[0-9]*" 2>/dev/null | grep $PKGNAME || echo "Package $PKGNAME is missed"
			echo "Local package $SRCRPM differs from the latest version from $RSYNCPATH"
		fi
	else
		SRCRPM="$PKGNAME-[0-9]*"
		RSYNCPATH=$(get_rsync_path $GIRARHOST $BINARYREPO)
		echog "Checking '$SRCRPM' in '$RSYNCPATH' ..."
		$RSYNC -n $RSYNCPATH/files/SRPMS/$SRCRPM 2>/dev/null | grep $PKGNAME
		echo "Package '$PKGNAME' is not installed locally"
	fi

	[ "$RET" = "OK" ]
	exit
fi

# FIXME: use mygetopts (LISTRPMARGS and so)

#if [ -n "$2" ] && [ "$1" = "all" ] ; then
#    shift
#    ALLSYSTEM=1
#fi

# DISABLED. TODO: REWRITE
# Check concrete system
# two params: system, package
if [ -n "$2" ] && false ; then
	PKGNAME=$2
	load_systems_list
	IDX=`get_system_idx "$1"`
	if [ -n "$IDX" ] ; then
		check_system $IDX
		print_list $NLIST
	else
		fatal "Unknown system '$1', use rpmgp -s for get list"
		#PKGNAME=
	fi
	exit 0
fi

# Check all systems
if [ -n "$ALLSYSTEM" ] ; then
	load_systems_list
	# search throw all systems
	for ((i=0; i < ${#SYSNAME[*]}; i++)) ; do
		echo
		check_system $i
		print_list $NLIST
	done
	exit 0
fi

fatal "Support for get src.rpm from ALT rsync removed. Use rpmgp with -g option"
