#!/bin/bash
#---
## @Synopsis Spell creator script for SourceMage GNU/Linux
## @Copyright Copyright 2006 SourceMage GNU/Linux
## @License GPL v2 or higher
##
## @ToDo Add option to use upstream gpg signature as included or
## @ToDo downloadable .sig file
## @ToDo Put a multiversion option
## @ToDo single line or multiline depending on the length of line if
## @ToDo <80 single else multi
## @ToDo Interface to add CONFIGURE options
## @ToDo Automated bugcli submissions of spells
## @ToDo Automatic inclusion into a grimoire when finished
## @ToDo Add a better configuration interface(dialog based I hope)
## @ToDo Make it possible to also update spells using quill
## @ToDo Make quill the be-all for spells
## @ToDo Make quill interface with grimoire to get functions
##
## Asks the user in simple questions about generating a spell.
## @Globals BUILDISON, INSTALLISON, PREBUILDISON, TRIGGERSISON
## @Globals SPELL_HISTORY_NAME, SPELL_HISTORY_EMAIL, SPELL_NAME,
## @Globals SPELL_SRC_URL, SPELL_LICENSE, SPELL_URL, SPELL_SHORT_DESCRIPTION,
## @Globals SPELL_DESCRIPTION, SPELL_DEPENDENCIES, SPELL_OPTIONAL_DEPENDENCIES,
## @Globals SPELL_CONFLICTS, HISOTRY_DATE, SPELL_SRC_FILE,
## @Globals SPELL_SANITIZED_FILE_NAME, SPELL_MD5_UNPACKED, SPELL_VERSION,
## @Globals i, j, n, BUILD_DTFILE, DTFILE_MENUENTRY, DTFILE_EXEC
## @Globals DTFILE_MENUPATH, DTFILE_ICON, DTFILE_TERM, SPELL_SRC_DIR
##
## @Thanks BearPerson, dufflebunk, afrayedknot
## @Thanks To all testers
## @Contribution abouter, lynxlynxlynx, iuso
##
#---
QUILL_VERSION="$(< /var/lib/quill/version)"
#---
## really basic stuff that should be loaded and set
. /var/lib/sorcery/modules/libmedia
LOCAL_MEDIA_CONFIG=/etc/sorcery/local/media source /etc/sorcery/media
function message() { echo -e "$@"; }
. /var/lib/quill/modules/libcore
## end of skeletal prerequisites - we get the rest later

QUILL_MODE="apprentice"
HISTORY_DATE="$(date +%Y-%m-%d)"
#---
## Not really a function it's supposed to parse the command line parameters
#---
while  [  -n  "$1"  ];  do
  if  echo  "" $1  |  grep  -q  "^ -";  then
    case  $1  in
      --fmxml|-f)
                  [[ -z $2 ]] &&
                  message "${PROBLEM_COLOR}Missing parameter$DEFAULT_COLOR" &&
                  quill_help 101
                  export QUILL_FMXML_MODE="on"; export QUILL_TARGET="$2"
                  shift 2 ;;
   --perlcpan|-c)
                  [[ -z $2 ]] &&
                  message "${PROBLEM_COLOR}Missing parameter$DEFAULT_COLOR" &&
                  quill_help 101
                  export QUILL_CPAN_MODE="on"; export QUILL_TARGET="$2"
                  shift 2 ;;
     --update|-u) export QUILL_UPDATE="on" QUILL_TARGET="$2"; shift 2 ;;
 --apprentice|-a) export QUILL_MODE="apprentice"; shift 1 ;;
       --mage|-m) export QUILL_MODE="mage"; shift 1 ;;
     --wizard|-w) export QUILL_MODE="wizard"; shift 1 ;;
--reconfigure|-r) export QUILL_MODE="reconfigure"; shift 1 ;;
       --help|-h) quill_help ;;
    --version|-v) quill_version ;;
               *) message "${PROBLEM_COLOR}Invalid parameter $1$DEFAULT_COLOR"
                  quill_help 102;;
    esac
  else
    shift
  fi
done
unset -f message
. /etc/sorcery/config
EDITOR=${EDITOR:-nano}
for i in /var/lib/quill/modules/lib*
do
  . $i
done

QUILL_HOME_DIR=~/.sourcemage/quill
QUILL_QUILLRC=${QUILL_HOME_DIR}/quillrc
QUILL_OLD_QUILLRC=~/.quillrc
QUILL_SPELL_DIR=~/.sourcemage/spells
QUILL_TMP_DIR=~/.sourcemage/tmp

quill_rc
# we should do some quillrc sanity checking someday
[[ ! -d $QUILL_SPELL_DIR ]] &&
  echo "PEBKAC: bad QUILL_SPELL_DIR ($QUILL_SPELL_DIR)" &&
  exit 7

PROMPT_DELAY="31557807"
BUILD_API=2
load_build_api
mkdir -p $QUILL_TMP_DIR

## Down to here... from here it's question and answer time
#---

#---
## Questions and stuff

quill_welcome
if [[ "$QUILL_FMXML_MODE" == "on" ]]
then
  # fetches SPELL_NAME, SPELL_DESC_NAME, SPELL_SRC_URL, SPELL_URL,
  # SPELL_LICENSE and both descriptions
  quill_fmxml_core $QUILL_TARGET

  # creates SPELL_VERSION and SPELL_SRC_FILE (to be SOURCE)
  parse_spell_source_file_info
fi

if [[ "$QUILL_CPAN_MODE" == "on" ]]
then
  quill_cpan_core $QUILL_TARGET
fi

if [[ "$QUILL_UPDATE" == "ion" ]]
then
  while true; do
    SPELL_NAME=$QUILL_TARGET
    if ! codex_does_spell_exist $SPELL_NAME
    then
      message "${PROBLEM_COLOR}$SPELL_NAME is not a spell!$DEFAULT_COLOR"
      exit 6
    fi

    actions=("Update the spell to a newer version" \
             "Manage patches" \
             "Convert to gpg signing" \
             "Add a \$SCM version" \
             "Try it out" \
             "Quit" )
    query_list "What do you want to do?" ANSWER "${actions[@]}"

    [[ $ANSWER == "Quit" ]] && exit 0

    #copy spell over and move there
    rm -fr $QUILL_SPELL_DIR/$SPELL_NAME
    cp -rv $(codex_find_spell_by_name $SPELL_NAME) $QUILL_SPELL_DIR
    cd $QUILL_SPELL_DIR/$SPELL_NAME

    case "$ANSWER" in
      "${actions[0]}") #"Update the spell to a newer version"
        #fetch current versions, ignoring SCM ones
        versions=( $(sed -n 's/\s*\<VERSION=//p' DETAILS |
                   grep -Eiv '\$[(]date *+|cvs|svn|tla|git|scm') )
        message "Current relevant version(s): ${versions[@]}"

        #suggest the new one from fm and/or ask for input
        for version in "${versions[@]}"
        do
          if query "Do you want to update $version?" y
          then
            query_spell_version

            #save the chosen version
            sed -i "s/\<VERSION=$version\>/VERSION=$SPELL_VERSION/" DETAILS

            #check for multiversion spells
            if [[ $(grep -c "\<SOURCE=") != 1 ]]
            then #we have problems
              message "Oh dear, detected a multiversion spell. Going to cat DETAILS for you "
              message "and then you will tell me which variable I need to set, so I can get "
              message "to the correct version ($SPELL_VERSION)."
              sleep 3
              cat DETAILS
              query_string if_var "${QUERY_COLOR}Please enter the appropriate variable. Example: UGU_DEVEL=y${DEFAULT_COLOR}"
            fi

            #check that (usually new) source urls are ok
            sources_and_urls=$($if_var; . /DETAILS &> /dev/null; get_spell_files_and_urls)
            sources=$(sed 's/^\(\S*\)\s.*$/\1/' <<< "$sources_and_urls" )
            source_urls=$(sed 's/^\S*\s*\(.\S*\)\s.*$/\1/' <<< "$sources_and_urls" )
            i=
            for su in $source_urls
            do
              wget -S --spider "$su" 2>&1 | grep -q "ERROR 404"
              #... if they are not ask for fixed ones
              if [[ $? != 0 ]]
              then
                message "SOURCE${i}_URL[0] is ok!"
              else
                message  "SOURCE${i}_URL[0] is broken! Fix it manually."
                quill_edit DETAILS
              fi
              let i=+1
            done

            #recheck that (usually new) source urls are ok
            #FIXME: avoid duplication by moving this in a function
            sources_and_urls=$($if_var; . /DETAILS &> /dev/null; get_spell_files_and_urls)
            sources=$(sed 's/^\(\S*\)\s.*$/\1/' <<< "$sources_and_urls" )
            source_urls=$(sed 's/^\S*\s*\(.\S*\)\s.*$/\1/' <<< "$sources_and_urls" )

            #download; we are not a grimoire so some hacking is needed
            summon -r <<< "$sources_and_urls"

            #get hashes and save them, removing any previous hash/gpg
            i=
            for source in $sources
            do
              hash=$(quill_hash_get $source)
              current_check=$( $if_var; . /DETAILS &> /dev/null; eval echo \$SOURCE${i}_HASH\$SOURCE${i}_GPG\$SOURCE${i}_IGNORE)

              #skip SOURCE_IGNORE
              if grep -Eq "volatile|signature|unversioned" <<< "$current_check"
              then
                [[ ! $i ]] && i=1
                let i=+1
                continue
              fi

              #SOURCE_GPG?
              if ! grep -Eq "(sha(512|256|1)|md5):.*:" <<< "$current_check"
              then #it is a gpg
                if ! query "Do you want to replace SOURCE${i}_GPG with a hash?" n
                then
                  message "Here is the hash for SOURCE$i anyway, if you need it later: $hash"
                  [[ ! $i ]] && i=1
                  let i=+1
                  continue
                fi
              fi

              #it is either a SOURCE_HASH or the user wants to replace SOURCE_GPG
              sed -ir "s/^(\s*)SOURCE${i}_(GPG|HASH)=$current_check$/\1SOURCE${i}_HASH=$hash/" DETAILS
              [[ ! $i ]] && i=1
              let i=+1
            done

            #restore patchlevel
            sed -i "/^[^#]*\<PATCHLEVEL=/d" DETAILS
          fi
        done

#update HISTORY
add_history_entries "DETAILS: updated to $SPELL_VERSION"

#copy the spell back to the grimoire?
#FIXME: root only, fix the end of quill first
cp -rv $QUILL_SPELL_DIR/$SPELL_NAME $(codex_find_spell_by_name $SPELL_NAME|dirname)

message "Done with updating the spell!"

        echo ++"$ANSWER"++ ;;
      "${actions[1]}") #"Manage patches"
#update patchlevel?
#update HISTORY
#copy the spell back to the grimoire?
        echo ++"$ANSWER"++ ;;
      "${actions[2]}") #"Convert to gpg signing"
#update HISTORY?
#copy the spell back to the grimoire?
        echo ++"$ANSWER"++ ;;
      "${actions[3]}") #"Add a \$SCM version"
#update patchlevel?
#update HISTORY
#copy the spell back to the grimoire?
        echo ++"$ANSWER"++ ;;
      "${actions[4]}") #"Try it out"
#check if there is anything to try out
  #if not just continue
#copy the spell back to the grimoire
#cast
        echo ++"$ANSWER"++ ;;
    esac

  done
else
  query_spell_name
  query_spell_source_url
  query_spell_license
  query_spell_url
  query_spell_short_description
  query_spell_description
  query_spell_dependencies
  query_spell_optional_dependencies
  query_spell_build
  query_spell_install
  query_spell_desktop_file

  if [[ "${QUILL_MODE}" == "mage" ]] || [[ "${QUILL_MODE}" == "wizard" ]]
  then
    query_spell_pre_build
    query_spell_prepare
    query_spell_conflicts
    #-query_spell_configure
    query_spell_provides
    #-query_spell_final
    #-query_spell_triggers
    #-query_spell_solo
    #-query_spell_configs
    #-query_spell_volatiles
    if [[ "${QUILL_MODE}" == "wizard" ]]
    then
      #-  query_spell_pre_install
      #-  query_spell_post_install
      #-  query_spell_pre_remove
      #-  query_spell_post_remove
      #-  query_spell_pre_resurrect
      #-  query_spell_post_resurrect
      true
    fi
  fi


  create_spell_base

  if [[ "${SPELL_DEPENDENCIES}" != "" ]]
  then
    add_dependencies
  fi

  if [[ "${SPELL_OPTIONAL_DEPENDENCIES}" != "" ]]
  then
    add_optional_dependencies
  fi

  # add && where appropriate in DEPENDS
  if [[ ${SPELL_OPTIONAL_DEPENDENCIES} != "" ]] || [[ ${SPELL_DEPENDENCIES} != "" ]]
  then
    sed -e 's/^ *$//' -e 's/[^\\]$/& \&\&/' DEPENDS | tac |
      awk '{ if (removed!=1){ if (sub("&&$","") > 0){ removed=1 }}; print }' |
      tac > temporary-DEPENDS
    mv temporary-DEPENDS DEPENDS
  fi

  if [[ "${SPELL_CONFLICTS}" != "" ]]
  then
    add_conflicts
  fi

  if [[ "${SPELL_PROVIDES}" != "" ]]
  then
    add_provides
  fi

  # redo it for fmxml - so it works if the xml didn't contain a valid source url
  # first time for other modes
  parse_spell_source_file_info
  show_spell_source_file_info
  echo

  get_spell_source

  hunt_src_dir

  add_details

  if [[ "${PREPAREISON}" == "PREPARE, " ]]
  then
    add_prepare
  fi

  #-if [[ "${CONFIGUREISON}" == "CONFIGURE, " ]]
  #-then
  #-  add_configure
  #-fi

  if [[ "${PREBUILDISON}" == "PRE_BUILD, " ]]
  then
    add_pre_build
  fi

  if [[ "${BUILDISON}" == "BUILD, " ]]
  then
    add_build
  fi

  if [[ "${INSTALLISON}" == "INSTALL, " ]]
  then
    add_install
  fi

  #-if [[ "${POSTINSTALLISON}" == "POST_INSTALL, " ]]
  #-then
  #-  add_post_install
  #-fi

  #-if [[ "${TRIGGERSISON}" == "TRIGGERS, " ]]
  #-then
  #-  add_triggers
  #-fi

  if [[ "${BUILD_DTFILE}" != "" ]]
  then
    add_desktop_file
  fi

  add_history
  quill_set_executable_bit
  if query "Do you want to edit all the spell files?" n
  then
    quill_edit
  fi
  if query "Do you want to tarball the spell?" n
  then
    quill_final_tarball
  fi
  message ""
  message "The spell has been generated and put into: $QUILL_SPELL_DIR/$SPELL_NAME"
  if query "Do you want to put the spell into one of the avialable grimoires?" n
  then
    quill_final_put_in_grimoire
  fi
fi
message "That's all folks!"

#---
##
## This software is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This software 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 General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this software; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##
#---
