#!/usr/bin/env bash
#===============================================================================
#
# DIRECTORY:
#   ---
#
# FILE:
#   ./applications_plugin.sh
#
# USAGE:
#     . applications_plugin.sh
#   OR
#     source applications_plugin.sh
#
# DESCRIPTION:
#   Applications_plugin plugin (library) to generate content with simple template engine.
#
# BUGS:
#   ---
#
# TESTS:
#   - shellcheck -s bash -e SC2034 ./applications_plugin.sh
#   - shellcheck -s ksh -e SC2034 ./applications_plugin.sh
#   - shellcheck -s dash -e SC2034 ./applications_plugin.sh
#
# AUTHOR:
#   Patrick Neumann, patrick@neumannsland.de
#
# COAUTHOR(S):
#   Odin Heitmann, odin.heitmann@gmail.com
#
# COMPANY:
#   (privately)
#
# VERSION:
#   1.0
#
# LINK TO THE MOST CURRENT VERSION:
#   (Sorry, we bet, I'm not allowed to publish it over GitHub!)
#
# CREATED:
#   2018-06-01
#
# COPYRIGHT (C):
#   2018 - Patrick Neumann & Odin Heitmann
#
# LICENSE:
#   This program 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 3 of the License, or
#   (at your option) any later version.
#
# WARRANTY:
#   This program 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 program. If not, see <http://www.gnu.org/licenses/>.
#
# NOTES:
#   ---
#
# TODO:
#   ---
#
# HISTORY:
#   1.0 - P. N. & O. H. - Initial (for the trainers eyes only) release
#
#===============================================================================

#-------------------------------------------------------------------------------
# Check if functions library is loaded first.
#-------------------------------------------------------------------------------
if [ "${FUNCTIONS_LOADED}" != "true" ] ; then
  printf "\\n\\033[01;31;40mERROR: functions library not loaded... EXIT!!!\\033[00m\\n\\n"
  exit 200
fi

#-------------------------------------------------------------------------------
# Check if temblate engine library is loaded first.
#-------------------------------------------------------------------------------
if [ "${TEMPLATE_ENGINE_LOADED}" != "true" ] ; then
  error_exit "template_engine.sh not loaded" 200
fi

#=== CONFIGURATION (static) ====================================================
#assign_binary "xyz"                                         # (un)common

#=== FUNCTION ==================================================================
# NAME: process_plists
# DESCRIPTION: ...
# PARAMETER1 : string (file)
#===============================================================================
process_plists () {
  # Apps are not part of the iTunes Backup!
  plist_bin2xml "${1}" "/tmp/iTunesMetadata.plist"
  local APP_ID="$( ${BIN_GREP} --fixed-strings --after-context=1 "softwareVersionBundleId" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  local APP_NAME="$( ${BIN_GREP} --fixed-strings --after-context=1 "bundleDisplayName" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  local APP_VERSION="$( ${BIN_GREP} --fixed-strings --after-context=1 "bundleVersion" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  local APP_DEVELOPER="$( ${BIN_GREP} --fixed-strings --after-context=1 "artistName" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  local APP_PURCHASED="$( ${BIN_GREP} --fixed-strings --after-context=1 "purchaseDate" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  local APP_APPLEID="$( ${BIN_GREP} --fixed-strings --after-context=1 "AppleID" /tmp/iTunesMetadata.plist \
	             | ${BIN_TAIL} -n 1 \
	             | ${BIN_SED} "${SED_EXT_REGEXP}" 's|[[:space:]]*</?string>||g' )"
  # In dash, string replacement is not supported
	# Because in dash, string replacement is not supported we can not use:
	#   echo ${1/${IOS_BACKUP}/\/private\/var}
  ${BIN_PRINTF} "<li><a href='${APP_ID}-iTunesMetadata.plist' target='_blank'><code>$( ${BIN_PRINTF} "${1}" | ${BIN_SED} "s|${IOS_BACKUP}|/private/var|" )</code></a></li>\\n" >> /tmp/apps_sources.html
  ${BIN_PRINTF} "<tr>\\n
            <td>${APP_ID}</td>\\n
            <td>${APP_NAME}</td>\\n
            <td>${APP_VERSION}</td>\\n
            <td>${APP_DEVELOPER}</td>\\n
            <td>${APP_PURCHASED}</td>\\n
            <td>${APP_APPLEID}</td>\\n
          </tr>\\n" >> /tmp/apps_list.html
  ${BIN_MV} /tmp/iTunesMetadata.plist "${FOLDER}/${APP_ID}-iTunesMetadata.plist"
}

#=== FUNCTION ==================================================================
# NAME: get_applications_list
# DESCRIPTION: "Grep" information and store into vars.
# PARAMETERS: none (global vars will be used.)
#===============================================================================
get_applications_list () {
  # Default applications visible by a user taken from iOS 10.3.3 
  readonly DEFAULT_APPS_LIST1="<li>Phone</li>
            <li>Safari</li>
            <li>Mail</li>
            <li>Music</li>
            <li>Messages</li>
            <li>Calendar</li>
            <li>Photos</li>
            <li>Camera</li>"
						
  readonly DEFAULT_APPS_LIST2="<li>Weather</li>
            <li>Clock</li>
            <li>Maps</li>
            <li>Videos</li>
            <li>Wallet</li>
            <li>Notes</li>
            <li>Reminders</li>
            <li>Stocks</li>"
						
  readonly DEFAULT_APPS_LIST3="<li>iTunes</li>
            <li>App Store</li>
            <li>iBooks</li>
            <li>Health</li>
            <li>Home</li>
            <li>Settings</li>
            <li>FaceTime</li>
            <li>Calculator</li>"
						
  readonly DEFAULT_APPS_LIST4="<li>Podcasts</li>
            <li>Watch</li>
            <li>Compass</li>
            <li>Tips</li>
            <li>Voice Memos</li>
            <li>Contacts</li>
            <li>Find Friends</li>
            <li>Find iPhone</li>"

  # Some possible sources for informations:
	#   - Phone:        /private/var/mobile/Library/CallHistory/CallHistory.storedata
	#       or:         5a4935c78a5255723f707230a451d79c540d2741
  #
  #   - Safari:       /private/var/mobile/Library/Safari/Bookmarks.db
	#       or:         d1f062e2da26192a6625d968274bfda8d07821e4
  #
  #   - Mail:        "/private/var/mobile/Library/Envelope Index"
	#       or:         ???
  #
  #   - Messages:     /private/var/mobile/Library/SMS/sms.db
	#       or:         3d0d7e5fb2ce288813306e4d4636395e047a3d28
  #
  #   - Calendar:     /private/var/mobile/Library/Calendar/Calendar.sqlitedb
	#       or:         2041457d5fe04d39d0ab481178355df6781e6858
  #
  #   - Notes:        /private/var/mobile/Library/Notes/notes.sqlite
	#       or:         ca3bc056d4da0bbf88b5fb3be254f3b7147e639c
  #
  #   - iTunes Store: /private/var/mobile/Library/com.apple.itunessotred/iTunesMetadata/itunessored2.sqlitedb
	#       or:         ???
  #
  #   - Contacts:     /private/var/mobile/Library/AddressBook/AddressBook.sqlitedb
	#       or:         31bb7ba8914766d4ba40d6dfb6113c8b614be442

  readonly APP_DIR="mobile/Containers/Bundle/Application"

  if ! [ -d "${IOS_BACKUP}/${APP_DIR}" ] ; then
    error  "${IOS_BACKUP}/${APP_DIR} not found"
    readonly APPS_LIST_HTML="<tr><td class='highlight' colspan='6'>ERROR: app directory not found!</td></tr>"
  else

	  # Not 100% save but easy! Will break if newlines are in the path to the plist!
	  ${BIN_FIND} "${IOS_BACKUP}"/mobile/Containers/Bundle/Application -name "iTunesMetadata.plist" \
	    | while read -r file ; do process_plists "${file}" ; done

	  APPS_SOURCES_HTML="$( ${BIN_CAT} /tmp/apps_sources.html )"
	  ${BIN_RM} /tmp/apps_sources.html

	  if [ -z "${APPS_SOURCES_HTML}" ] ; then
	    APPS_SOURCES_HTML="<li>none</li>"
	  fi

	  readonly APPS_LIST_HTML="$( ${BIN_CAT} /tmp/apps_list.html )"
	  ${BIN_RM} /tmp/apps_list.html

  fi

  if [ "${DEBUG}" = "on" ] ; then
    ${BIN_PRINTF} "INFO: applications_plugin processed.\\n" 1>&2
	fi
}

#-------------------------------------------------------------------------------
# Partial template for applications information for the simple template engine.
#-------------------------------------------------------------------------------
# SC2034: all "unused" vars are verified!
APPLICATIONS_INFORMATION=$( ${BIN_CAT} <<'EOF'
          <h2>Applications</h2>
          <h3>Preinstalled</h3>
			    <div class='ym-grid ym-equalize linearize-level-1'>
			      <div class='ym-g50 ym-gl'>
		          <div class='ym-grid'>
		            <div class='ym-g50 ym-gl'>
                  <div class='ym-gbox'>
                    <ul>
		                  ${DEFAULT_APPS_LIST1}
                    </ul>
		              </div>
		            </div>
		            <div class='ym-g50 ym-gr'>
                  <div class='ym-gbox'>
                    <ul>
	                    ${DEFAULT_APPS_LIST2}
                    </ul>
		              </div>
		            </div>
              </div>
			      </div>
			      <div class='ym-g50 ym-gr'>
		          <div class='ym-grid'>
		            <div class='ym-g50 ym-gl'>
                  <div class='ym-gbox'>
                    <ul>
		                  ${DEFAULT_APPS_LIST3}
                    </ul>
		              </div>
		            </div>
		            <div class='ym-g50 ym-gr'>
                  <div class='ym-gbox'>
                    <ul>
	                    ${DEFAULT_APPS_LIST4}
                    </ul>
		              </div>
		            </div>
              </div>
            </div>
			    </div>
			    <h4>Sources</h4>
			    <ul class="file">
			      ${APPS_SOURCES_HTML}
			    </ul>
          <h3>Installed by user</h3>
          <table>
            <tr>
              <th>AppID</th>
              <th>Name</th>
              <th>Version</th>
              <th>Developer</th>
              <th>Purchased</th>
              <th>AppleID</th>
            </tr>
            ${APPS_LIST_HTML}
					</table>
EOF
)

readonly APPLICATIONS_PLUGIN_LOADED="true"

if [ "${DEBUG}" = "on" ] ; then
  ${BIN_PRINTF} "INFO: applications_plugin.sh loaded.\\n" 1>&2
fi
# Do not use "exit" at the end of a sourced library!