#! /bin/sh
#
#   Copyright (c) 2015 Nat! - Mulle kybernetiK
#   All rights reserved.
#
#   Redistribution and use in source and binary forms, with or without
#   modification, are permitted provided that the following conditions are met:
#
#   Redistributions of source code must retain the above copyright notice, this
#   list of conditions and the following disclaimer.
#
#   Redistributions in binary form must reproduce the above copyright notice,
#   this list of conditions and the following disclaimer in the documentation
#   and/or other materials provided with the distribution.
#
#   Neither the name of Mulle kybernetiK nor the names of its contributors
#   may be used to endorse or promote products derived from this software
#   without specific prior written permission.
#
#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
#   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
#   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
#   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
#   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
#   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
#   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
#   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
#   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
#   POSSIBILITY OF SUCH DAMAGE.

MULLE_BOOTSTRAP_VERSION="2.0"

#
# This is the main user interface to mulle-bootstrap
# sorta like git
#

trap_fail()
{
   exit 1
}


usage()
{
   cat <<EOF
usage: mulle-bootstrap [options] [command] [--help]
 Common Options:
   -a -y     : default answer to questions (scripts wont be checked)
               -a (clone preferred) -y (local copy/symlink preferred)
   -n        : do nothing creative or destructive
   -v        : -v to be more verbose (-vv or -vvv for more verbosity)
   -V        : show build commands

 Common user commands:
   bootstrap : does fetch and build recursively [default]
   clean     : cleans mulle-bootstrap produced files.

 Common maintainer commands:
   init      : initializes a bootstrap project
EOF

   if [ "${UNAME}" = 'darwin' ]
   then
      cat <<EOF
   xcode     : sets up xcodeproj settings
EOF
   fi

cat <<EOF
   tag       : tag this project and fetched repositories

 Specialized commands:
   build     : builds fetched repositories
   fetch     : fetches required repositories recursively. Use it after updating
               the repositories and embedded_repositories files.
   update    : updates repositories (pull).
   install   : install dependencies as system headers
EOF
   exit 1
}


ensure_consistency()
{
   local owd

   owd="`pwd -P`"

   if [ -f "${CLONESFETCH_SUBDIR}/.fetch_update_started" ]
   then
      log_error "A previous fetch or update was incomplete.
Suggested resolution (in $owd):
    ${C_RESET_BOLD}mulle-bootstrap clean dist${C_ERROR}
    ${C_RESET_BOLD}mulle-bootstrap${C_ERROR}

Or do you feel lucky ? Then try again with
   ${C_RESET_BOLD}mulle-bootstrap -f${C_ERROR}
But you've gotta ask yourself one question: Do I feel lucky ?
Well, do ya, punk?"
      exit 1
   fi
}


bootstrap_main()
{
   local command

   BOOTSTRAP_SUBDIR=.bootstrap

   PATH="/usr/local/libexec/mulle-bootstrap:`pwd -P`/dependencies/bin:`pwd -P`/addictions/bin:$PATH"
   export PATH

   #
   # shell export commands with minimal
   # trap setup
   #
   case "${1}" in
      library-path)
         echo "$PATH" | tr ':' '\012' | head -1
         exit 0
      ;;

      version)
         echo "${MULLE_BOOTSTRAP_VERSION}"
         exit 0
      ;;
   esac


   MULLE_BOOTSTRAP_PID="$$"
   export MULLE_BOOTSTRAP_PID

   # now include this first to get
   # logging and UNAME

   . mulle-bootstrap-logging.sh

   trap trap_fail INT

   #
   # simple option handling
   #
   while [ $# -ne 0 ]
   do
      case "$1" in
         -a|--prefer-origin)
            MULLE_BOOTSTRAP_ANSWER="NO"
          ;;

         -y|--prefer-local)
            MULLE_BOOTSTRAP_ANSWER="YES"
         ;;

         -f|--force-fetch)
            MULLE_BOOTSTRAP_DIRTY_HARRY="NO"
         ;;

         -n|--dry-run)
            MULLE_EXECUTOR_DRY_RUN="YES"
         ;;

         -ig|--ignore-graveyard)
            MULLE_BOOTSTRAP_IGNORE_GRAVEYARD="YES"
         ;;

         -te|--trace-execution)
            MULLE_EXECUTOR_TRACE="YES"
         ;;

         -tm|--trace-settings-merge)
            MULLE_BOOTSTRAP_TRACE_MERGE="YES"
         ;;

         -ts|--trace-scripts)
            MULLE_BOOTSTRAP_TRACE_SCRIPT_CALLS="YES"
         ;;

         -tt|--trace-ignores-settings)
            MULLE_BOOTSTRAP_SETTINGS_FLIP_X="YES"
         ;;

         -t|--trace)
            MULLE_BOOTSTRAP_TRACE="1848"
            COPYMOVEFLAGS="-v"
            GITFLAGS="-v"
         ;;

         -V|--verbose-build)
            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
         ;;

         -v|--verbose)
            MULLE_BOOTSTRAP_TRACE="VERBOSE"
            COPYMOVEFLAGS="-v"
            GITFLAGS="-v"
         ;;

         -vv|--very-verbose)
            MULLE_BOOTSTRAP_TRACE="FLUFF"
            COPYMOVEFLAGS="-v"
            GITFLAGS="-v"
         ;;

         -vvv|--very-verbose-with-settings)
            MULLE_BOOTSTRAP_TRACE="TRACE"
            COPYMOVEFLAGS="-v"
            GITFLAGS="-v"
         ;;

         -r|--refresh)
            MULLE_BOOTSTRAP_SKIP_INITIAL_REFRESH="YES"
         ;;

         -s|--silent)
            MULLE_BOOTSTRAP_TRACE=
            MULLE_BOOTSTRAP_TERSE="YES"
            GITFLAGS="-q"
         ;;

         -h|--help)
            usage
         ;;

         -*)
            log_error "unknown option \"$1\""
            usage
         ;;

         *)
            break
         ;;
      esac

      shift
   done

   case "${MULLE_BOOTSTRAP_TRACE}" in
      VERBOSE)
         MULLE_BOOTSTRAP_FLUFF="NO"
         MULLE_BOOTSTRAP_VERBOSE="YES"
         if [ -z "${MULLE_BOOTSTRAP_VERBOSE_BUILD}" ]
         then
            MULLE_BOOTSTRAP_VERBOSE_BUILD="NO"
         fi
         ;;

      FLUFF)
         MULLE_BOOTSTRAP_FLUFF="YES"
         MULLE_BOOTSTRAP_VERBOSE="YES"
         MULLE_EXECUTOR_TRACE="YES"
         if [ -z "${MULLE_BOOTSTRAP_VERBOSE_BUILD}" ]
         then
            MULLE_BOOTSTRAP_VERBOSE_BUILD="NO"
         fi
         ;;

      TRACE)
         MULLE_BOOTSTRAP_TRACE_SETTINGS="YES"
         MULLE_EXECUTOR_TRACE="YES"
         MULLE_BOOTSTRAP_FLUFF="YES"
         MULLE_BOOTSTRAP_VERBOSE="YES"
         if [ -z "${MULLE_BOOTSTRAP_VERBOSE_BUILD}" ]
         then
            MULLE_BOOTSTRAP_VERBOSE_BUILD="NO"
         fi
         log_trace "FULL trace started"
         ;;

      1848)
         MULLE_BOOTSTRAP_TRACE_SETTINGS="NO"
         MULLE_EXECUTOR_TRACE="NO"
         MULLE_BOOTSTRAP_FLUFF="NO"
         MULLE_BOOTSTRAP_VERBOSE="NO"
         if [ -z "${MULLE_BOOTSTRAP_VERBOSE_BUILD}" ]
         then
            MULLE_BOOTSTRAP_VERBOSE_BUILD="YES"
         fi
         log_trace "1848 trace (set -x) started"
         set -x
         ;;
   esac

   if [ "${MULLE_EXECUTOR_DRY_RUN}" = "YES" ]
   then
      log_trace "Dry run is active."
   fi

   #
   # some commands only run when we have a .bootstrap folder
   #
   command=${1:-"bootstrap"}
   [ $# -eq 0 ] || shift

   if [ ! -d "${BOOTSTRAP_SUBDIR}" ]
   then
      case "${command}" in
         bootstrap|nomagic|build|ibuild|refresh|dist|clean|dist-clean|fetch|update|setup-xcode|xcode|tag)
            fail "There is no ${BOOTSTRAP_SUBDIR} folder here, can't continue"
      esac
   fi

   if [ "${MULLE_BOOTSTRAP_DIRTY_HARRY}" != "NO" ]
   then
      case "${command}" in
         clean|dist-clean|init)
            :
         ;;
         *)
            ensure_consistency
         ;;
      esac
   fi

   # some commands refresh before execution
   if [ "${MULLE_BOOTSTRAP_SKIP_INITIAL_REFRESH}" != "YES" ]
   then
      case "${command}" in
         bootstrap|nomagic|setup-xcode|xcode|tag|fetch)
           . mulle-bootstrap-refresh.sh
            refresh_main || exit 1
         ;;

         build)
           . mulle-bootstrap-refresh.sh

            refresh_main refresh_if_bare || exit 1
         ;;

         update|refresh)
           . mulle-bootstrap-refresh.sh

           # 4 laters
         ;;
      esac
   fi

   case "${command}" in
      bootstrap|nomagic)
         if [ "${command}" = "nomagic" ]
         then
            DONT_RECURSE=YES
         fi

         . mulle-bootstrap-fetch.sh
         . mulle-bootstrap-build.sh
         . mulle-bootstrap-warn-scripts.sh

         if [ "${DONT_RECURSE}" = "" ]
         then
            fetch_main "$@"     || exit 1
            refresh_main                  || exit 1
        else
            fetch_main --non-recursive "$@" || exit 1
            refresh_main nonrecursive    || exit 1
         fi

         warn_scripts_main "${BOOTSTRAP_SUBDIR}" || exit 1

         # do it again now!
         build_main "$@" || exit 1
      ;;

      # experimental stuff
      project)
         . mulle-bootstrap-project.sh

         project_main "$@" || exit 1
      ;;

      install)
         . mulle-bootstrap-install.sh

         install_main "$@" || exit 1
      ;;

      build)
         . mulle-bootstrap-build.sh

         build_main "$@" || exit 1
      ;;

      refresh)
         refresh_main "$@" || exit 1
      ;;

      clean)
         . mulle-bootstrap-clean.sh

         clean_main "$@"    || exit 1
      ;;

      dist)
         . mulle-bootstrap-clean.sh

         clean_main "dist"    || exit 1
      ;;

      fetch)
         . mulle-bootstrap-fetch.sh

         DONT_ASK_AFTER_WARNING=YES fetch_main "$@" || exit 1
         refresh_main || exit 1
      ;;

      update)
         . mulle-bootstrap-fetch.sh

         update_main "$@" || exit 1
         refresh_main || exit 1
      ;;

      init)
         . mulle-bootstrap-init.sh

        init_main "$@" || exit 1
      ;;

      setup-xcode|xcode)
         . mulle-bootstrap-xcode.sh

         xcode_main "$@" || exit 1
      ;;

      tag)
         . mulle-bootstrap-tag.sh

         tag_main "$@" || exit 1
      ;;

      library-path)
         echo "$PATH" | tr ':' '\012' | head -1
         exit 0
      ;;

      version)
         echo "${MULLE_BOOTSTRAP_VERSION}" || exit 1
      ;;

      *)
         log_error "Unknown command \"${command}\""
         usage
      ;;
   esac
}

bootstrap_main "$@"