##############################################################################
# Copyright (c) Members of the EGEE Collaboration. 2004. 
# See http://www.eu-egee.org/partners/ for details on the copyright 
# holders.  
#
# Licensed under the Apache License, Version 2.0 (the "License"); 
# you may not use this file except in compliance with the License. 
# You may obtain a copy of the License at 
#
#    http://www.apache.org/licenses/LICENSE-2.0 
#
# Unless required by applicable law or agreed to in writing, software 
# distributed under the License is distributed on an "AS IS" BASIS, 
# WITHOUT WARRANTIES OR CONDITIONS 
# OF ANY KIND, either express or implied. 
# See the License for the specific language governing permissions and 
# limitations under the License.
##############################################################################
#
# NAME :        config_mkgridmap
#
# DESCRIPTION : This function creates the necessary configuration files to
#               create the grid-map file. 
#
# AUTHORS :     Maarten.Litmaath@cern.ch
#               Gergely.Debreczeni@cern.ch
#               Robert.Harakaly@cern.ch
#               Maria.Alandes.Pradillo@cern.ch
#
# NOTES :       - LFC, FTS and DPM need special mkgridmap configuration.
#               - There is a config_vomsmap function for voms-map files. 
#               - Old lcmaps configuration files are no longer created.
#
# YAIM MODULE:  glite-yaim-core
#                 
##############################################################################

function config_mkgridmap_check () {
                                                                                                                             
  requires $1 INSTALL_ROOT USERS_CONF GROUPS_CONF VOS VO__VOMS_SERVERS GRIDMAPFILE CONFIG_GRIDMAPDIR
  ret=$?

  if ( echo " ${NODE_TYPE_LIST} " | egrep -q "CE|SCAS|CLUSTER|storm" ) && ( ! echo " ${NODE_TYPE_LIST} " | egrep -q 'creamCE' ); then
    requires $1 DN_GRIDMAPFILE
    let "ret |= $?"
  fi

  if [ $ret -ne 0 ]; then
    return 1
  fi
  return 0
}
                                                                                                                             
function config_mkgridmap_setenv () {
  yaimlog DEBUG "This function currently doesn't set any environment variables."
}

config_mkgridmap () {

  ###@ Check if edg-mkgridmap has been installed

#  if [ ! -f  ${INSTALL_ROOT}/edg/libexec/edg-mkgridmap/edg-mkgridmap.pl ]; then
#    yestr ${YEX_NOSUCHFILE}
#    yaimlog ERROR "${INSTALL_ROOT}/edg/libexec/edg-mkgridmap. edg-mkgridmap is probably not installed !"
#    yaimlog ERROR "${YERRORSTR}"
#    exit ${YEX_NOSUCHFILE}
#  fi

#temporary here the definition of INSTALL_ROOT
INSTALL_ROOT=/usr

  if [ ! -f  ${INSTALL_ROOT}/libexec/edg-mkgridmap/edg-mkgridmap.pl ]; then
    yestr ${YEX_NOSUCHFILE}
    yaimlog ERROR "${INSTALL_ROOT}/libexec/edg-mkgridmap/edg-mkgridmap.pl is probably not installed !"
    yaimlog ERROR "${YERRORSTR}"
    exit ${YEX_NOSUCHFILE}
  fi

# to completly remove the following lines
#  ###@ Remove old lcas/lcmaps configuration files if they still exist
#  if [ -f ${INSTALL_ROOT}/edg/etc/lcmaps/gridmapfile ]; then
#    yaimlog DEBUG "Removing old lcmaps gridmapfile that it's no longer used..."
#    rm -f ${INSTALL_ROOT}/edg/etc/lcmaps/gridmapfile 
#  fi
#  if [ -f ${INSTALL_ROOT}/edg/etc/lcmaps/groupmapfile ]; then
#    yaimlog DEBUG "Removing old lcmaps groupmapfile that it's no longer used..."
#    rm -f ${INSTALL_ROOT}/edg/etc/lcmaps/groupmapfile
#  fi

  ####@ Node types that need grid-map file and voms-map file need a different path 
  if ( echo " ${NODE_TYPE_LIST} " | egrep -q "SCAS|storm" ) && ( ! echo " ${NODE_TYPE_LIST} " | egrep -q "creamCE|WMS|CLUSTER" ); then
    gmf=${DN_GRIDMAPFILE}
  else
    gmf=${GRIDMAPFILE}
  fi

  ####@ Check whether USERS_CONF exists
  if [ ! -e $USERS_CONF ]; then
    yaimlog ERROR "USERS_CONF ${USERS_CONF} not found"
    yestr ${YEX_NOSUCHFILE}
    yaimlog ERROR "${YERRORSTR}"
    exit ${YEX_NOSUCHFILE}
  fi

  ####@ Check whether GROUPS_CONF exists
  if [ ! -e $GROUPS_CONF ]; then
    yaimlog ERROR "GROUPS_CONF ${GROUPS_CONF} not found"
    yestr ${YEX_NOSUCHFILE}
    yaimlog ERROR "${YERRORSTR}"
    exit ${YEX_NOSUCHFILE}
  fi

  ####@ Check the format of users in USERS_CONF
  check_users_conf_format

  yaimlog DEBUG "Defining the grid-map file configuration file location and the gridmapdir"

  ####@ LFC and FTS standard grid-map file location is not needed
  if ( echo " ${NODE_TYPE_LIST} " | egrep -qi ' (LFC|FTS) ' ); then
    gmc=/dev/null
  else
    gmc=/etc/edg-mkgridmap.conf
    yaimlog DEBUG "Configuration file in ${gmc}"
  fi
  gmd=/etc/grid-security/gridmapdir
  yaimlog DEBUG "gridmapdir in ${gmd}"

  if [ "x${CONFIG_GRIDMAPDIR}" == "xyes" ]; then
    ####@ DPM: the $gmd directory should be owned by root:dpmmgr
    if ( ! echo "${NODE_TYPE_LIST}" | egrep -qi 'LFC|FTS|SE_castor' ); then
      mkdir -p $gmd
      if ( echo "$NODE_TYPE_LIST" | egrep -qi "dpm" ); then 
        chown root:${DPMMGR_GROUP} $gmd
      elif ( echo "$NODE_TYPE_LIST" | egrep -q "WMS" ); then
        chown root:${GLITE_GROUP} $gmd
      else
        chown root:${EDG_GROUP} $gmd
      fi
      chmod 770 $gmd
    fi
  fi

  ####@ DPM and LFC: special grid-mapfile configuration file"
  if ( echo "${NODE_TYPE_LIST}" | egrep -qi 'dpm|LFC' ); then
    gmc_dm=/etc/lcgdm-mkgridmap.conf
    yaimlog DEBUG "Configuration file in ${gmc_dm}"
  else
    gmc_dm=/dev/null
  fi

  ####@ FTS: special grid-mapfile configuration file"
  if ( echo "${NODE_TYPE_LIST}" | egrep -qi 'FTS' ); then
    gmc_fts=/etc/submit-mkgridmap.conf
    yaimlog DEBUG "Configuration file in ${gmc_fts}"
  else
    gmc_fts=/dev/null
  fi

  cat << EOF > $gmc
##############################################################################
#
# edg-mkgridmap.conf generated by YAIM on `date`
#
##############################################################################

EOF

  cat << EOF > $gmc_dm
##############################################################################
#
# lcgdm-mkgridmap.conf generated by YAIM on `date`
#
##############################################################################

EOF

  cat << EOF > $gmc_fts
##############################################################################
#
# submit-mkgridmap.conf generated by YAIM on `date`
#
##############################################################################

EOF

  ####@ Loop for each VO
  for VO in `echo $VOS | tr '[:lower:]' '[:upper:]'`; do
    yaimlog DEBUG "**** VO ${VO} ****" 
    ####@ Set some variables
    voms_servers=`get_vo_param ${VO} VOMS_SERVERS`
    VO_lower=`echo $VO | tr '[:upper:]' '[:lower:]'`
    vo_group=`users_getvogroup $VO`
    vo_user_prefix=`users_getvoprefix $VO`
    [ -z "$vo_user_prefix" ] && vo_user_prefix=$VO_lower

    yaimlog DEBUG "The voms servers are ${voms_servers}"
    yaimlog DEBUG "VO_lower is ${VO_lower}"
    yaimlog DEBUG "VO group is ${vo_group}" 
    yaimlog DEBUG "The user prefix is ${vo_user_prefix}"

    if [ "x${CONFIG_GRIDMAPDIR}" == "xyes" ]; then
      ####@ gridmapdir files
      yaimlog DEBUG "create gridmapdir files"
      if ( ! echo "${NODE_TYPE_LIST}" | egrep -qi 'LFC|FTS|SE_castor' ); then
        for user in `awk -F: '$5 == "'$VO_lower'" && $2 ~ /[0-9]$/ {print $2}' $USERS_CONF`; do
          f=$gmd/$user
          [ -f $f ] || touch $f
        done
      fi
    else
      yaimlog INFO "No gridmapdir files are created since CONFIG_GRIDMAPDIR=no"
    fi

    ####@ Pool accounts prefix
    if ( echo "${NODE_TYPE_LIST}" | egrep -q 'SE_castor' ); then
      vo_pool_account=`users_getfirstpoolaccount $VO`
  	  [ -z "$vo_pool_account" ] && exit 1
    else
	    vo_pool_account=.$vo_user_prefix
    fi
    yaimlog DEBUG "The pool account prefix is ${vo_pool_account}"
 
    ####@ mkgridmap configuration file
    vo_match="/${VO_lower}"
    lcg_prefix="/VO=${VO_lower}/GROUP="
    echo "# $VO" >> $gmc

    
    value=`get_vo_param ${VO} UNPRIVILEGED_MKGRIDMAP`
    if [ "x${value}" == "xyes" ]; then
      yaimlog INFO "The grid-map file will *NOT* contain special users for VO ${VO} since UNPRIVILEGED_MKGRIDMAP=yes for the VO."
    else  
      if [ "x${value}" == "xno" ] || [ "x${value}" == "x" ]; then
      yaimlog INFO "The grid-map file will also contain special users for VO ${VO} since UNPRIVILEGED_MKGRIDMAP=no for the VO." 
      ####@ Create special accounts
      vo_tags=`	awk -F: '$4!="" && $1~"^\"(/VO=[^/]*/GROUP=)?" vo_match "[/\"]" && seen[$4]++ == 0 { print $4 }
	                      ' vo_match=$vo_match $GROUPS_CONF`
      yaimlog DEBUG "VO tags are ${vo_tags}"
      for special in $vo_tags; do
        eval ${special}users='`users_getspecialusers $VO $special`'
        eval ${special}group=`users_getspecialgroup $VO $special`
        eval ${special}prefix=`users_getspecialprefix $VO $special`
    	  eval u=\$${special}users
    	  case $u in
      	  ?*' '?*) use_pool_accounts=true;;
	        *) if grep -q ":${u%% *}:.*," $USERS_CONF; then
               case $u in
            		*[0-9]) yaimlog WARNING "Only 1 pool account defined for tag '$special' of VO $VO"
                		    use_pool_accounts=true ;;
          		  *) # static account defined with multiple groups
         	         use_pool_accounts=false
          	   esac
	           else
        	     use_pool_accounts=false
	           fi
	      esac

	      case $SPECIAL_POOL_ACCOUNTS in
	        [1TtYy]*) use_pool_accounts=true;;
	        [0FfNn]*) use_pool_accounts=false;;
	        ?*) yaimlog WARNING "SPECIAL_POOL_ACCOUNTS has a wrong value '$SPECIAL_POOL_ACCOUNTS'"
	      esac

	      if ( echo "${NODE_TYPE_LIST}" | egrep -q 'SE_castor|VOBOX' ); then
	        use_pool_accounts=false
	      fi

	      if $use_pool_accounts && ! grep -q ":${u%% *}:.*," $USERS_CONF; then
	        yaimlog ERROR "Pool accounts for tag '$special' of VO $VO need multiple groups"
	      fi

	      if ! $use_pool_accounts; then
	        eval ${special}_pool_account="\${${special}users%% *}"
	        eval u=\$${special}_pool_account
	      else
	        eval ${special}_pool_account=.\$${special}prefix
	        eval u=.\$${special}prefix
	      fi
	      test "x$u" = x. && continue
	      special_match='^"'"$vo_match"'\(/[^"]*\).*:'"$special":
        yaimlog DEBUG "special match is ${special_match}"

	      if [ "$u" -a "$voms_servers" ]; then
	      
	        # we must handle all these cases:
	        #
	        # "/dteam/ROLE=lcgadmin":::sgm:
	        # "/dteam/ROLE=production":::prd:
	        # "/lhcb/sgm":::sgm:
	        # "/lhcb/lcgprod":::prd:
	        # "/lhcb/sgm/ROLE=something":::sgm:
	        # "/lhcb/lcgprod/ROLE=something":::prd:
	      
	        sed -n '
		      s|^"/VO=[^/]*/GROUP=|"|
		      s|'"$special_match"' *$|\1|p
		      s|'"$special_match$VO_lower"':* *$|\1|p
	        ' $GROUPS_CONF | sed 's/ROLE/Role/i' | uniq | while read attr; do
  		      echo "$attr"
  		      echo "# Map VO members ($special)" >> $gmc
  		      split_quoted_variable $voms_servers | while read server; do
		          echo "group ${server%/}$attr $u"        >> $gmc
		          echo "group ${server%/}$attr $VO_lower" >> $gmc_dm
		          echo "group ${server%/}$attr $VO_lower" >> $gmc_fts
		        done
		      echo >> $gmc
	        done | grep . > /dev/null || yaimlog WARNING "Cannot find VOMS FQAN for $special user '$u' - skipping"
	      fi 
      done # vo_tags
      fi # UNPRIVILEGED_MKGRIDMAP=no
    fi # UNPRIVILEGED_MKGRIDMAP=yes

    ####@ Ordinary users
    ord_users=""
    ord_users=`more ${GROUPS_CONF} | awk -F: '$1 == "\"/'$VO_lower'\"" { print $1 }'`
    if [ "x${ord_users}" != "x" ]; then
      yaimlog INFO "Adding ordinary users in the gridmap file since the VO is defined in groups.conf"
      if [ "$voms_servers" ]; then
        echo "# Map VO members (root group)" >> $gmc
        split_quoted_variable $voms_servers | while read server; do
          echo "group ${server%/} $vo_pool_account" >> $gmc
          echo "group ${server%/} $VO_lower"        >> $gmc_dm
          echo "group ${server%/} $VO_lower"        >> $gmc_fts
        done
        echo >> $gmc
      fi
    fi
    echo >> $gmc

    ####@ clean for next VO
    for special in $vo_tags; do
      eval ${special}_pool_account=
      eval ${special}group=
    done

  done # End of VO loop

  f=/etc/grid-mapfile-local

  [ -f $f ] || touch $f

  cat << EOF >> $gmc
#############################################################################
# Local grid-mapfile to bootstrap the actual grid-mapfile:
# can be used to allow extra DNs or override some mappings.

gmf_local $f

EOF

  if [ ${gmc_dm:-/dev/null} != /dev/null ]; then
    f=/etc/lcgdm-mapfile-local
    [ -f $f ] || touch $f
  fi

  cat << EOF >> $gmc_dm
gmf_local $f
EOF

  if [ ${gmc_fts:-/dev/null} != /dev/null ]; then
    f=/etc/submit-mapfile-local
    [ -f $f ] || touch $f
  fi

  cat << EOF >> $gmc_fts
gmf_local $f
EOF

  minute=
  h1=

  ####@ All nodes except FTS and LFC:  mkgridmap cronjob and logrotate
  if ( ! echo "${NODE_TYPE_LIST}" | egrep -qi '\<(FTS|LFC)' ); then
    f=/var/log/edg-mkgridmap.log
    cmd="$INSTALL_ROOT/sbin/edg-mkgridmap --output=${gmf} --safe"
    yaimlog INFO "Now creating the grid-mapfile - this may take a few minutes..."
    $cmd 2>> $YAIM_LOG
    let minute="$RANDOM%60"
    let h1="$RANDOM%6"
    let h2="$h1+6"
    let h3="$h2+6"
    let h4="$h3+6"
    cron_job edg-mkgridmap root "$minute $h1,$h2,$h3,$h4 * * * (date; $cmd) >> $f 2>&1"
    touch $f
    cat > /etc/logrotate.d/edg-mkgridmap <<EOF
$f {
    weekly
    compress
    rotate 4
    missingok
}
EOF
  fi

  ####@ DPM and LFC:  mkgridmap cronjob and logrotate
  if ( echo "${NODE_TYPE_LIST}" | egrep -qi 'dpm|LFC' ); then
     f=/var/log/lcgdm-mkgridmap.log
     cmd="$INSTALL_ROOT/libexec/edg-mkgridmap/edg-mkgridmap.pl \
          --conf=$gmc_dm --output=/etc/lcgdm-mapfile --safe"
     yaimlog INFO "Now creating the lcgdm-mapfile - this may take a few minutes..."
     $cmd 2>> $YAIM_LOG
     #
     # ensure the DPM has both cron jobs run at the same times,
     # to avoid bizarre authorization problems for new users
     #
     let minute="${minute:-$RANDOM%60}"
     let h1="${h1:-$RANDOM%6}"
     let h2="$h1+6"
     let h3="$h2+6"
     let h4="$h3+6"
     cron_job lcgdm-mkgridmap root "$minute $h1,$h2,$h3,$h4 * * * (date; $cmd) >> $f 2>&1"
     touch $f
     cat > /etc/logrotate.d/lcgdm-mkgridmap <<EOF
$f {
    weekly
    compress
    rotate 4
    missingok
}
EOF
  fi

  ####@ FTS: mkgridmap cronjob and logrotate 
  if ( echo "${NODE_TYPE_LIST}" | egrep -qi 'FTS' ); then
    f=/var/log/glite-data-transfer-submit-mkgridmap.log
    cmd="$INSTALL_ROOT/libexec/edg-mkgridmap/edg-mkgridmap.pl \
         --conf=$gmc_fts --output=/etc/glite-data-transfer-submit-mapfile --safe"
    yaimlog INFO "Now creating the glite-data-transfer-submit-mapfile - this may take a few minutes..."
    $cmd 2>> $YAIM_LOG
    let minute="$RANDOM%60"
    let h1="$RANDOM%6"
    let h2="$h1+6"
    let h3="$h2+6"
    let h4="$h3+6"
    cron_job glite-data-transfer-submit-mkgridmap root "$minute $h1,$h2,$h3,$h4 * * * (date; $cmd) >> $f 2>&1"
    touch $f
    cat > /etc/logrotate.d/glite-data-transfer-submit-mkgridmap <<EOF
$f {
    weekly
    compress
    rotate 4
    missingok
}
EOF
  fi

  ####@ lcg-expiregridmapdir
  if ( echo "${NODE_TYPE_LIST}" | grep -q '\<'RB ); then
    cron_job lcg-expiregridmapdir root  "5 * * * * \
    ${INSTALL_ROOT}/sbin/lcg-expiregridmapdir.pl -e 240 -v >> \
    /var/log/lcg-expiregridmapdir.log 2>&1"
  elif ( echo "${NODE_TYPE_LIST}" | egrep -qi 'LFC|FTS|SE_castor|VOBOX' ); then
    # No expiry
    rm -f ${CRON_DIR}/lcg-expiregridmapdir
  else
    cron_job lcg-expiregridmapdir root  "5 * * * * \
    ${INSTALL_ROOT}/sbin/lcg-expiregridmapdir.pl -v >> \
    /var/log/lcg-expiregridmapdir.log 2>&1"
  fi

unset INSTALL_ROOT

return 0

}
