#!/usr/bin/env bash

print_help() {
    cat <<EOF
USAGE

  $(basename "$0") (-h|--help)
  $(basename "$0") [-a|-v|--verbose] (Bibcode | [Year.]Journal.Volume.Page | [author|title words])


# Bibcode with/without Author letter; with/without '&/+'
# eg : simref2 2020A+A...634L...4

DESCRIPTION


PARAMETERS


TODO
  # year author/title -> where author like '' or title like '' ?
  1967 Yamashita
  2024 Gravitational Waves
  
  # ajouter sortie %q (%J ?)
  -cite
  # author/title
  LEUNG C.

EXAMPLES

>  $(basename "$0") 2024A+A...683L..17
%R 2024A&A...683L..17S
%DOI 10.1051/0004-6361/202449736
%A SHAPOSHNIKOV I.A.
%A CHEREPASHCHUK A.M.
%A DODIN A.V.
%A POSTNOV K.A.
%J Astron. Astrophys., 683L, 17 (2024)
%T Spectroscopic searches for evolutionary orbital period changes in WR+OB binaries: The case of WR 127 (Hen 3-1772).
%V (abstract)
%O=4

> From author/title
> $(basename "$0")  LEUNG C.


EXIT STATUS

 - 0   Everything fine
 - 1   Input error

AUTHORS

  Grégory Mantelet
  Anaïs Oberto

VERSION

  25th April 2024
EOF
}


# exit on error
#set -e 

INPUT=""
VERBOSE=0
COUNT_AUTHORS=0
# ...read all parameters:
while (( "$#" ))
do
    # interpret each one:
    case "$1" in

        # CASE: HELP
        -h|--help)
            print_help
            exit 0
            ;;

        # CASE: AUTHORS
        -a)
            COUNT_AUTHORS=1
            ;;


        # CASE: VERBOSE
        -v|--verbose)
            VERBOSE=1
            ;;

        # CASE: ANY OTHER OPTION (just print a warning)
        -*)
            echo "WARNING: unknown option: '$1'! => Option ignored"
            ;;

		# CASE: BIBCODE OR WORDS
        *)
		INPUT="$*"
		break
		;;
    esac

    # go the next parameter:
    shift

done


################################################################################
#
# FUNCTION normalize_input(input)
#
# Re-arrange the input string more like a bibcode
#
# replace + -> &
# remove vizier prefix
# remove . between year and journal
# remove . before flag char
# add . after flag char
normalize_input() {
	tmp="$1"
	# replace + -> &
	tmp="${tmp/+/\&}"
	# remove vizier prefix
	tmp="${tmp/#J[. \/]other[. \/]//}"
	isvizprefix='J[/. ][A-Za-z][A-Za-z+]*[/. ]'
	if [[ "$tmp" =~ $isvizprefix ]]
	then
		tmp="${tmp/#J[. \/]/}"
	fi
	# remove . between year and journal
	if [[ "$tmp" =~ ^[12][890][0-9][0-9][.] ]]
	then
			tmp=${tmp:0:4}${tmp:5}
	fi
	# remove . before flag char
	# add . after flag char
	tmp=$(echo "$tmp" | sed -e 's/\([0-9]\)[.]\([A-Za-z]\)\([0-9]\)/\1\2.\3/')
	echo "$tmp"
}

################################################################################
#
# FUNCTION to_regexp(input)
#
# Transforms missing content to regexp
#
# add regexp for year before
# add possible letter after volume (number after journal)
# add all pages if no pages is given
# convert all multiple . with at least one .
# add possible letter/. at the end

to_regexp(){
	tmp="$1"
	# if does not start with a Year
	# eg journal.volume
	if [[ "$tmp" =~ ^[A-Za-z.]+ ]]
	then
		# add regexp for year before
		tmp="[12][890][0-9][0-9]${tmp}"
	fi
	
	# add possible letter after volume (number after journal)
	# and no letter already given, and pages is given
	# (Journal.Volume). -> \1[A-Za-z]?
	tmp=$(echo "$tmp" | sed -e 's/\([A-Za-z.]\+[0-9]\+\)[.]/\1[A-Za-z]?./')

	# convert all multiple . with at least one .
	tmp=$(echo "$tmp" | sed -e 's/[.]\+/[.][.]*/g')

	# add all pages if no pages is given
	# test on input, not modified string $tmp !
	if [[ ! "$1" =~ [0-9][A-Za-z]?[.][0-9] ]]
	then
		# add everything at the end
		tmp="$tmp"'.*'
	else
		# add possible letter/. at the end
		tmp="^${tmp}[A-Z.]?$"
	fi




	echo "$tmp"
}

######################################
# MAIN
######################################
if [ -z "$INPUT" ] 
then
	echo "ERROR: No input"
	exit 1
else
	# transforms , separator to .
	INPUT="${INPUT//, /.}"
	
	# more than one parameter /or/ only one word without numeric -> words to extract
	if [[ "$INPUT" =~ " " || ! "$INPUT" =~ [0-9] ]] 
	then
		# Input is Year Author/Title
		if [[ "$INPUT" =~ ^[12][890][0-9][0-9] ]]
		then
			input_year=${INPUT/ */}
			[ $VERBOSE -eq 1 ] && echo "  > Search in year $input_year"
			words=${INPUT//* /}
		else
			words="$INPUT"
		fi
		# add .* between words
		words=${words// /.* }
		[ $VERBOSE -eq 1 ] && echo "  > Search in title/author"
	
	# bibcode like
	else
		b="$INPUT"
		[ $VERBOSE -eq 1 ] && echo "  > Search in bibcode"
	fi
fi

if [ $COUNT_AUTHORS -eq 1 ]
then
	query="select author, count(*) from author where author ~ '^${words}' group by author;"
else
	if [ "${INPUT:0:1}" == "=" ]
	then
		condition="priv_com ~ '$INPUT'"

	elif [ -n "$b" ] 
	then
		# replace some specific characters
		b=$(normalize_input "$b")
		[ $VERBOSE -eq 1 ] && echo "  > Normalised to : $b"

		# prepare a regular expression according to the entry
		# checks if it is a regular bibcode (may be not last letter)
		# if [[ "$b" =~ $isbibcode && ${#b} -gt 18 ]]

		# if not a regular bibcode 
		# else
			# if does not start with a Year
			# eg journal.volume
		# 	if [[ "$b" =~ ^[A-Za-z.]* ]]
		# 	then
		# 		# add year before
		# 		b="[12][0-9][0-9][0-9]${b}[0-9A-Za-z.]*"
		# 	fi
		# fi

		b=$(to_regexp "$b")

		[ $VERBOSE -eq 1 ] && echo "  > Input changed to regexp : $b"
		condition="bibcode ~* '$b'"
	else
		if [ -n "$input_year" ]
		then
			condition_year="AND publi_year=$input_year"
		else
			condition_year=""
		fi
		condition="((title ~* '$words' OR author ~* '^${words}') $condition_year)"
	fi




		filters='
				"%R "    + .bibcode                 ,
				(if ((.doi | length) > 0) then "%DOI "  + .doi else empty end)                     ,
				"%A "    + (if ((.authors | length) > 0) then (.authors | map(.) | join("\n%A ")) else ".Anonymous" end),
				"%J "    + .journal + ", " + (.volume|tostring) + ", " + (.page|tostring) + "-" + (.last_page|tostring) ,
				"%T "    + .title                   ,
				"%K "    + (if ((.keywords | length) > 0) then (.keywords | map(.) | join("\n%K ")) else empty end),
				(if ((.priv_com | length)>0) then ("%W "    + .priv_com) else empty end)                ,
				(if ((.pub_com_files | length)>0) then ("%F "    + .pub_com_files) else empty end)           ,
				(if ((.pub_com_acro | length)>0) then ("%N "    + .pub_com_acro) else empty end)           ,
				(if ((.nbobject | length)>0) then ("%O="    + (.nbobject|tostring)) else "%O=0" end)     ,
				"%D "    + .bib_creation+" "+.bib_modif ,

				""
	'
	#             "%M "    + (."nb-pages" | tostring) ,
	#             "%B "    + .abstract                

	query="SELECT row_to_json(t) FROM 
		(SELECT distinct bib_ref.*, 
						 array(SELECT author FROM author as allauthors WHERE allauthors.oidbibref=oidbib ORDER BY aut_pos) as authors,
						 array(SELECT keyword FROM keywords as allkw WHERE allkw.oidbibref=oidbib) as keywords
		FROM bib_ref, author
		WHERE (oidbib=oidbibref AND $condition) ORDER BY bibcode) as t"

	#	(SELECT * FROM bib_ref, 
	#		(SELECT array(SELECT author FROM author JOIN bib_ref ON oidbibref=oidbib
	#				 WHERE $condition GROUP BY author, aut_pos ORDER BY aut_pos) AS authors)
	#		 AS authors WHERE $condition ORDER BY bibcode) as t"

fi


[ $VERBOSE -eq 1 ] && (echo -e "  > QUERY: $query\n" && exit 0)

data=$(psql -h simpg -d simbad -U guest -p5432 --tuples-only -c "$query")
tmpfile="/tmp/simref_$(uuidgen)"
if [ -z "$filters" ]
then
	echo "$data"
else
	echo "$data" > "$tmpfile" && echo "$data" | jq  -r "$filters" && rm "$tmpfile"
fi
