#!/bin/ksh -a
# Global variables
minKbFree=500000 # Minimum disk space for export in kB
defExportDir=/tmp/psExport # Default export directory
defImportDir=/tmp/psImport # Default import directory
startDir=`pwd` # Current directory
scriptDir=`dirname $0`
scriptDir=`(cd $scriptDir;pwd)` # Location of scripts
libDir=`(cd $scriptDir/../lib;pwd)` # Location of libraries
isFlatRole=0;

# I18n variables
TEXTDOMAIN=migrationtools
# Set the locale directory to $BASEDIR/SUNWps/migration/locale
TEXTDOMAINDIR=$scriptDir/../locale

# Desktop Migration variables
tempDesktop=/tmp/.temp_desktop # Temporary directory for desktop template migration

# LDAP Migration variables
reqversion=6.2
pkginfo=/etc/opt/SUNWps/PSConfig.properties # Pkginfo file that contains ps 6.x installation variables
jss_pkginfo=/var/sadm/pkg/SUNWjss/pkginfo # Pkginfo file that contains jss installation variables
CMDVERSION=1.0

# Executable locations
AWK=/usr/bin/awk
BC=/usr/bin/bc
CAT=/usr/bin/cat
CHMOD=/usr/bin/chmod
COMM=/usr/bin/comm
CP=/usr/bin/cp
DF=/usr/bin/df
DU=/usr/bin/du
ECHO=/usr/bin/echo
EGREP=/usr/bin/egrep
GETENT=/usr/bin/getent
GETTEXT=/usr/bin/gettext
LN=/usr/bin/ln
GREP=/usr/bin/grep
MKDIR=/usr/bin/mkdir
MV=/usr/bin/mv
OMIT_CHAR='\c'
PERL=/usr/bin/perl
PING=/usr/sbin/ping
PS=/usr/bin/ps
RM=/usr/bin/rm
SED=/usr/bin/sed
STTY=/usr/bin/stty
TAR=/usr/bin/tar
TOUCH=/usr/bin/touch
UNIQ=/usr/bin/uniq
WC=/usr/bin/wc

###############################################
# Show help information - CLIP standards
###############################################
helptext () {
  getVersionInfo
  print "`$GETTEXT 'convertps is used to migrate iPlanet Portal Server 3.0
(Service Pack 3a or 4) data to files that can be uploaded into
  '` $PNAME $PVERSION"
  print "`$GETTEXT '  OPTIONS
    -a Convert all modules (no menu)
    -f Converts roles to roles, instead of roles to sub-organizations
    -i <directory> where <directory> is iPS export directory
    -o <directory> where <directory> is place to save migrated files
       for future upload using importps'`"
  $ECHO ""
  exit 0
}

###############################################
# Show version information - CLIP standards
###############################################
versiontext () {
  getVersionInfo
  print "`$GETTEXT 'convertps ('`$PNAME $PVERSION`$GETTEXT ') '` $CMDVERSION"
  print "$COPYRIGHT"
  exit 0
}

###############################################
# Retrieve version information
###############################################
getVersionInfo() {
  GrabConfig "BASEDIR" $pkginfo "="
  VERSIONFILE="$ANSWER_CONFIG/SUNWps/lib/PSversion.properties"
  if [ ! -f $VERSIONFILE ]; then
    print "`$GETTEXT 'Error in installation.  File not found: '`$VERSIONFILE"
    exit 1
  fi
  GrabConfig "productname" $VERSIONFILE "="
  PNAME=$ANSWER_CONFIG
  GrabConfig "productversion" $VERSIONFILE "="
  PVERSION=$ANSWER_CONFIG
  GrabConfig "copyright" $VERSIONFILE "="
  COPYRIGHT=$ANSWER_CONFIG
  export PNAME PVERSION COPYRIGHT
}

###############################################
# Get configuration from file
###############################################
GrabConfig() {
  GRABCONFIG_KEY=$1
  GRABCONFIG_FILE=$2
  GRABCONFIG_SEPARATOR=$3
  ANSWER_CONFIG=`$GREP "^$GRABCONFIG_KEY$GRABCONFIG_SEPARATOR" $GRABCONFIG_FILE | $UNIQ | $SED -e "s/$GRABCONFIG_KEY$GRABCONFIG_SEPARATOR//" | $SED -e "s/^ //"`
}

###############################################
# Set JAVA_HOME
###############################################
SetupJDK() {
  local JDK_PKGINFO_FILE="/var/sadm/pkg/SUNWpsjdk/pkginfo"
  local DSAME_PKGINFO_FILE="/var/sadm/pkg/SUNWamsvc/pkginfo"

  if [ -f $JDK_PKGINFO_FILE ]; then
    GrabConfig "JDK_PATH" $JDK_PKGINFO_FILE "="
    JAVA_HOME=$ANSWER_CONFIG
  elif [ -f $DSAME_PKGINFO_FILE ]; then
    GrabConfig "JDK_BASE_DIR" $DSAME_PKGINFO_FILE "="
    JAVA_HOME=$ANSWER_CONFIG
  else
    print "`$GETTEXT 'Cannot set up JAVA_HOME.'` $BELL_CHAR"
    return 1
  fi
  return 0
}

###############################################
# Get the Elapsed Time
###############################################
GetElapsedTime(){
  LOC_START_SECONDS=$1
  LOC_END_SECONDS=$2

  if [ "$LOC_END_SECONDS" != "" ]; then
    TOTAL_SECONDS=`$ECHO $LOC_END_SECONDS $LOC_START_SECONDS | awk '{ print $1-$2 }'`
  else
    TOTAL_SECONDS=$LOC_START_SECONDS
  fi

  INSTALL_TIME=`$ECHO "scale=2; $TOTAL_SECONDS/60" | $BC`

  if [ $INSTALL_TIME -lt 2.00 ]; then
    eval print "`$GETTEXT 'Elapsed Time: $INSTALL_TIME minute or $TOTAL_SECONDS seconds.'`" >> $perfFile
  else
    eval print "`$GETTEXT 'Elapsed Time: $INSTALL_TIME minutes or $TOTAL_SECONDS seconds.'`" >> $perfFile
  fi
}


###############################################
# Trap CRTL-C
###############################################
Interrupt() {
  $STTY echo

  print ""
  print "`$GETTEXT 'Migration aborted.'`"

  exit 2
}


###############################################
# Verify IS User password, query if not set
###############################################
VerifyISUserPassword() {
  local PROMPT="Enter Identity Server Internal LDAP Authentication User password: "
  local DONE=""

  DONE="n"
  while [ "$DONE" = "n" ]; do
    eval print "$PROMPT \$OMIT_CHAR"
    $STTY -echo
    read ANSWER_CONFIG
    $STTY echo
    echo ""
    HAD_INPUT="y"
    if [ "$ANSWER_CONFIG" != "" ]; then
      (
        # check ldapsearch to verify password
        cd $ldapSharedDir
        LD_LIBRARY_PATH=$LDAPLIBDIR ./ldapsearch -A -h $DS_HOST -p $DS_PORT -D "cn=amldapuser,ou=DSAME Users,${DS_ROOT_SUFFIX}" -w $ANSWER_CONFIG \
          -b "${DS_ROOT_SUFFIX}" "(dn=*)" >/dev/null 2>/dev/null
      )
      if [ $? -ne 0 ]; then
        print "`$GETTEXT 'Password verification failed!'` $BELL_CHAR"
      else
        DONE="y"
      fi
    else
      print ""
    fi
  done
}


###############################################
# Verify DS Manager password, query if not set
###############################################
VerifyDSDMPassword() {
  local PROMPT="Enter Directory Manager password: "
  local DONE=""

  DONE="n"
  while [ "$DONE" = "n" ]; do
    eval print "$PROMPT \$OMIT_CHAR"
    $STTY -echo
    read ANSWER_CONFIG
    $STTY echo
    echo ""
    HAD_INPUT="y"
    if [ "$ANSWER_CONFIG" != "" ]; then
      (
        # check ldapsearch to verify password
        cd $ldapSharedDir
        LD_LIBRARY_PATH=$LDAPLIBDIR ./ldapsearch -A -h $DS_HOST -p $DS_PORT -D "$DS_DIRMGR_DN" -w $ANSWER_CONFIG \
          -b "${DS_ROOT_SUFFIX}" "(dn=*)" >/dev/null 2>/dev/null
      )
      if [ $? -ne 0 ]; then
        print "`$GETTEXT 'Password verification failed!'` $BELL_CHAR"
      else
        DONE="y"
      fi
    else
      print ""
    fi
  done
}


###############################################
# Verify correct version of PS installed on
# system.  Also pull all environment variables
# needed from the pkginfo file(s)
###############################################
verifyVersion () {
  if [ -f $pkginfo ]; then
    # Set the proper environment vars for version info
    getVersionInfo
# Grab all the environment variables we need
#    GrabConfig "DS_HOSTNAME" $pkginfo "="
#    DS_HOSTNAME=$ANSWER_CONFIG
    GrabConfig "IDSAME_BASEDIR" $pkginfo "="
    IDSAME_BASEDIR=$ANSWER_CONFIG
    GrabConfig "BASEDIR" $pkginfo "="
    BASEDIR=$ANSWER_CONFIG
    GrabConfig "DS_HOST" $pkginfo "="
    DS_HOST=$ANSWER_CONFIG
    GrabConfig "DS_PORT" $pkginfo "="
    DS_PORT=$ANSWER_CONFIG
    GrabConfig "DS_DIRMGR_DN" $pkginfo "="
    DS_DIRMGR_DN=$ANSWER_CONFIG

    FILE="/etc/opt/SUNWam/config/AMConfig.properties"
    if [ -f $FILE ]; then
      ADMINDN=`$GREP "^com.sun.identity.authentication.super.user=" $FILE | \
               $SED -e "s/com.sun.identity.authentication.super.user=//" `
      DS_ROOT_SUFFIX=`$GREP "^com.iplanet.am.rootsuffix=" $FILE | $SED -e "s/com.iplanet.am.rootsuffix=//"`
      DS_DEFAULT_ORG=`$GREP "^com.iplanet.am.defaultOrg=" $FILE | $SED -e "s/com.iplanet.am.defaultOrg=//"`
    else
      print "`$GETTEXT 'Error - Cannot find DSAME configuration file, please verify PS installation.'`"
      exit 1
    fi

    if [ "$DS_DEFAULT_ORG" != "$DS_ROOT_SUFFIX" ]; then
      ORG_DN="$DS_DEFAULT_ORG,$DS_ROOT_SUFFIX"
    else
      ORG_DN=$DS_DEFAULT_ORG
    fi

    # Get LDAP function library and binary locations
    LDAPLIBDIR="${IDSAME_BASEDIR}/SUNWam/ldaplib/ldapsdk"
    while test ! -f $LDAPLIBDIR/libldap50.so ; do
      print "`$GETTEXT 'Error - Cannot find ldap library directory. Please enter location: '`"
      read LDAPLIBDIR
    done
    ldapSharedDir="${IDSAME_BASEDIR}/SUNWam/bin"
    while test ! -f $ldapSharedDir/ldapsearch ; do
      print "`$GETTEXT 'Error - Cannot find ldap binary directory. Please enter location: '`"
      read ldapSharedDir
    done
    # Get JSS basedir for library and jar locations
    GrabConfig "BASEDIR" $jss_pkginfo "="
    JSS_BASEDIR=$ANSWER_CONFIG
    LDAPLIBDIR="$LDAPLIBDIR:${BASEDIR}/SUNWps/lib:${JSS_BASEDIR}/usr/lib/mps"
    
# Trying to put jss311.jar into installation
#    while test ! -f $jssDir/jss311.jar ; do
#      print "`$GETTEXT 'Error - Cannot find directory containing jss311.jar. Please enter location: '`"
#      read jssDir
#    done
    # Need JSS jar for ldap conversion
#    while test \( ! -x $ldapSharedDir/ldapsearch -o ! -f $LDAPLIBDIR/libldap50.so \) -o ! -f $LDAPDIR/java/jss311.jar ; do
#      print "`$GETTEXT 'Error - Cannot find ldap directory. Please enter directory location: '`"
#      read LDAPDIR
#      ldapSharedDir=$LDAPDIR/shared/bin
#    done

# Used by convertDesktop.pl
    GrabConfig "DEPLOY_URI" $pkginfo "="
    DEPLOY_URI=$ANSWER_CONFIG
    GrabConfig "SERVER_HOST" $pkginfo "="
    SERVER_HOST=$ANSWER_CONFIG
    GrabConfig "SERVER_PORT" $pkginfo "="
    SERVER_PORT=$ANSWER_CONFIG
    GrabConfig "SERVER_PROTOCOL" $pkginfo "="
    SERVER_PROTOCOL=$ANSWER_CONFIG

    STATIC_URI=$DEPLOY_URI
  else
    print "`$GETTEXT 'Please verify PS installation, cannot find SUNWps package information files'`"
    exit 1
  fi

# Verify version is proper
  if [ $PVERSION -ge $reqversion ]; then
    print "`$GETTEXT 'Found Portal Server version'` $PVERSION"
  else
    printf "`$GETTEXT 'Warning - Portal Server version %s detected, only version %s supported for conversion.'`\n" "$PVERSION" "$reqversion"
    question="`$GETTEXT 'Continue with conversion?'`"
    ans=`ckyorn -d n -p "$question" -Q`
    case $ans in
      [yY]*) :;;
      [nN]*) exit 1;;
      *) exit 1;;
    esac
  fi
  # Verify java
#  if [ -z "${JAVA_HOME}" ] ; then
#      if [ -d /usr/java ] ; then
#          JAVA_HOME=/usr/java
#      else
#          print "`$GETTEXT 'Error - JAVA_HOME environment variable not set.'`" 1>&2
#          exit 1
#      fi
#  fi

  SetupJDK
  if [ $? -ne 0 ]; then
    if [ ! -z ${JAVA_HOME} ]; then
      JAVA_HOME="${JAVA_HOME}"
    elif [  -d  "/usr/java" ]; then
      JAVA_HOME="/usr/java"
    else
      print "`$GETTEXT 'Error - Unable to find JDK directory.'`"
      exit 1
    fi
  fi
  if [ ! -x "$JAVA_HOME/bin/java" ]; then
    printf "`$GETTEXT 'Error: Unable to find %s'`\n" "$JAVA_HOME/bin/java"
    exit 1
  fi
  # The password is no longer stored in config files, must query user if
  # not passed in.  TBD create option to pass in dsdirmgr password
  #    GrabConfig "DS_DIRMGR_PASSWORD" $pkginfo "="
  VerifyDSDMPassword
  DS_DIRMGR_PASSWORD=$ANSWER_CONFIG
  VerifyISUserPassword
  LDAPUSER_PASSWD=$ANSWER_CONFIG
}

###############################################
# Remove temporary files and exit
###############################################
cleanAndExit () {
# Clean up temp files
  if [ -d $tempDesktop ]; then
    rm -rf $tempDesktop
  fi
  rm $moduleFile
  exit 0
}




###############################################
# Begin Main routine
###############################################

# Parse the command line options
for x in $@; do
  case $x in
    --help)  helptext;;
    --version)  versiontext;;
  esac
done

# Use the getops command for all single-character options
while getopts :afi:o: name; do
  case $name in
    a)         runAll=1;;
    i)         exportDir=$OPTARG;;
    o)         importDir=$OPTARG;;
    f)         isFlatRole=1;;
    ?)         print "`$GETTEXT 'Invalid option:'` $OPTARG\n"; helptext;;
  esac
done

trap Interrupt 2

# Verify correct version of PS is installed
verifyVersion

# Verify export directory
#until [ -f ${exportDir:=$defExportDir}/.export_complete ]; do
until [ -d ${exportDir:=$defExportDir} ]; do
  print "`$GETTEXT 'Warning - Directory doees not exist:'` $exportDir."
  print "`$GETTEXT 'Which directory contains the export data?'` [$defExportDir] \c"
  read -r newExportDir
  exportDir=${newExportDir:-$defExportDir}
done
# For some reason this one variable is never marked for export, must do it manually
export exportDir
# Get the FQP of exportDir
exportDir=`(cd $exportDir;pwd)`

# Verify import directory
if [ "$importDir" = "" ];then
  print "`$GETTEXT 'Which directory should be created to store the converted data?'` [$defImportDir] \c"
  read -r newImportDir
  importDir=${newImportDir:-$defImportDir}
fi
if [ -d $importDir ]; then
  importDir=`(cd $importDir;pwd)`

  if [ $exportDir = $importDir ]; then
    print "`$GETTEXT 'Error - The import and export directories are identical.'`"
    exit 1
  fi

  printf "`$GETTEXT 'Import directory %s already exists.'`\n" "$importDir"
  print "`$GETTEXT 'If you do not wish to overwrite data within this directory, please exit this migration process and rename the directory.'`"
  question="`$GETTEXT 'Delete the directory'` $importDir?"
  ans=`ckyorn -d n -p "$question" -Q`
  case $ans in
    [yY]*) rm -rf $importDir;;
    *) print "`$GETTEXT 'Continuing conversion'`";;
  esac
fi

if [ ! -d $importDir ]; then
  mkdir -p $importDir
fi

kbFree=`df -b $importDir | tail -1 | awk '{print $2}'`
if [ $kbFree -lt $minKbFree ]; then
  printf "`$GETTEXT 'Import directory %s only has %s kB free, %s is required'`\n" "$importDir" "$kbFree" "$minKbFree"
  exit 1
fi
# Get the FQP of importDir
importDir=`(cd $importDir;pwd)`

# Create the import directories
if [ ! -d $importDir/logs ]; then
  mkdir -m 777 $importDir/logs
fi
errorFile=$importDir/logs/error.$$
reportFile=$importDir/logs/report.$$
perfFile=$importDir/logs/convert_metrics.$$

print "`$GETTEXT 'Begin conversion process at'` `date`" | tee $errorFile $reportFile $perfFile
START_SCRIPT_TIME=`date`
print "`$GETTEXT 'Error file:'` $errorFile"
print "`$GETTEXT 'Report file:'` $reportFile"
print "`$GETTEXT 'Metric file:'` $perfFile"

echo ""
SECONDS=0

# Run menu and selected modules
processType="convert"
moduleFile=/tmp/.module$$

# Get the module list
for x in `find $scriptDir/../modules -type f -perm -100 -name "*$processType"`; do
  moduleID=`basename $x`
  gc=`echo $moduleID | grep -c '^[0-9][0-9]'`
  if [ $gc -ge 1 ]; then
    echo "$moduleID $x" >> $moduleFile
  fi
done

#echo "List of modules"
sort $moduleFile > $moduleFile.2
mv $moduleFile.2 $moduleFile

if [ "$runAll" == "1" ]; then
  for x in `cat $moduleFile | awk '{print $2}'`; do
    (cd `dirname $x`;. ./`basename $x`)
    if [ $? -ne 0 ]; then
      print "`$GETTEXT 'Error - Convert abort in module'` `basename $x`" | tee -a $errorFile $reportFile
      rm $moduleFile*
      exit 1
    fi
  done
else
  # Get menu entries for each file in order
  print "`$GETTEXT 'Conversion Menu'`"
  itemCount=1
  FS=
  menuItems=
  for x in `cat $moduleFile | awk '{print $2}'`; do
    menuItem=`. $x --menu | head -1`
    if [ "$menuItem" != "" ]; then
      menuItems="$menuItems$FS$menuItem"
      menuExe[$itemCount]=$x
      let itemCount=itemCount+1;
      FS="'"
    else
      echo "`basename $x` $x" >> $moduleFile.2
    fi
  done
  #echo $menuItems
  # Find what the user wants to do
  PS3="`$GETTEXT 'Select one of the listed options to convert:'` "
  OLDIFS=$IFS
  IFS=$FS
  select x in $menuItems "`$GETTEXT 'All of the above'`" "`$GETTEXT 'Exit'`"; do
    IFS=$OLDIFS
    case "$x" in
      "`$GETTEXT 'All of the above'`") for x in `cat $moduleFile | awk '{print $2}'`; do
            (cd `dirname $x`;. ./`basename $x`)
            if [ $? -ne 0 ]; then
              print "`$GETTEXT 'Error - Convert abort in module'` `basename $x`" | tee -a $errorFile $reportFile
              rm $moduleFile*
              exit 1
            fi
          done
          break;;
      "`$GETTEXT 'Exit'`") cleanAndExit 0;;
      *) numReply=`echo $REPLY | sed s/[^0-9]//g`
         if [ "$numReply" != "$REPLY" ]; then
           print "`$GETTEXT 'Invalid selection'` - $REPLY"
         elif [ $REPLY -le 0 -o $REPLY -ge 1024 ]; then
           print "`$GETTEXT 'Invalid selection'` - $REPLY"
         elif [ "${menuExe[$REPLY]}" != "" ]; then
           echo "`basename ${menuExe[$REPLY]}` ${menuExe[$REPLY]}" >> $moduleFile.2
           for x in `sort $moduleFile.2 | awk '{print $2}'`; do
             (cd `dirname $x`;. ./`basename $x`)
             if [ $? -ne 0 ]; then
               print "`$GETTEXT 'Error - Convert abort in module'` `basename $x`" | tee -a $errorFile $reportFile
               rm $moduleFile*
               exit 1
             fi
           done
           break
         else
           print "`$GETTEXT 'Invalid selection'` - $REPLY"
         fi ;;
    esac
  done
fi

GetElapsedTime "$SECONDS"
print "`$GETTEXT 'Successful completion of conversion process at'` `date`" | tee -a $errorFile $reportFile $perfFile
echo ""
echo ""
cleanAndExit 0
