#!/bin/bash

# ------------------------------------------- #
# Repository and bundle setup variables.
# ------------------------------------------- #

# The usual application name
APPLICATION_NAME=pitivi

# Where to build the FLATPAK
FLATPAK_ENVPATH=${FLATPAK_ENVPATH:-$HOME/$APPLICATION_NAME-flatpak}

# The name of the bundled application (must respect flatpak app application naming convention).
APPLICATION_REF_NAME=org.pitivi.Pitivi

# Local path to the application repository
APPLICATION_REPOSITORY=${APPLICATION_REPOSITORY:-$FLATPAK_ENVPATH/$APPLICATION_NAME}

# The name given to the application in the .desktop file
APPLICATION_DESKTOP_NAME="(Daily) Pitivi"
# The default branch to use and create if generating the bundle
BRANCH="master"

# The URL of the bundle remote repository
APPLICATION_FLATPAK_REPO=http://flatpak.pitivi.org
APPLICATION_FLATPAK_REPO_FILE=http://flatpak.pitivi.org/pitivi.flatpakrepo

# The name to give to the repository if it is not registered in flatpak yet
APPLICATION_DEFAULT_REPO_NAME=pitivi

# The name of the runtime to build the bundle against
RUNTIME_NAME=org.gnome.Platform
# The name of the Sdk to build the bundle against
SDK_NAME=org.gnome.Sdk
# The version of the Sdk to build the bundle against
SDK_VERSION=3.20
# The URL of the Sdk remote repository
SDK_REPO=http://sdk.gnome.org/repo/
SDK_REPO_FILE=https://sdk.gnome.org/gnome.flatpakrepo
# The name to give to the repository if it is not registered in flatpak yet
SDK_DEFAULT_REPO_NAME=gnome

GST_VERSION=master

# ------------------------------------------- #

# Some terminal output color values
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'

HELP="Helper script to work with flatpak for $APPLICATION_NAME

Options:
=======

General:
-------
  -u,  --update:     Update the runtime/sdk/app and rebuild the development environment if needed
  -n,  --no-update:  Do not update anything (By default we update bundles when not in development mode)

Development:
-----------
  -d,  --devel:      Setup a devel environment, meaning that it et you in
                     a bash environment ready to work on $APPLICATION_NAME, not that the environment
                     will be 'read only' and you will be only able to work on $APPLICATION_NAME
                     itself easily. To have more control, you should use the --build option.
  -b,  --build:      Build $APPLICATION_NAME and its dependencies inside a flatpak environment.
  -b=, --branch=:    The flatpak branch to use (0.95, master...)
  -c,  --clean:      Clean previous builds and restart from scratch
       --use-remote: Build from the official repository (master branch)

Building bundle for distribution:
--------------------------------
       --bundle:                  Create bundle repository in $REPO, implies --build
       --repo-commit-subject:     The commit subject to be used when updating the ostree repository
       --repo-commit-body:        The commit body to be used when updating the ostree repository
       --check:                   Run make check on Pitivi (work only when --bundle is used)
       --gpg-sign=KEYID:          The GPG key to sign the commit with (work only when --bundle is used)
       --generate-static-deltas:  Do not generate static deltas (check 'man flatpak-build-update-repo'
                                  for more informations)

You can find more information about flatpak at: http://flatpak.org/
"

for i in "$@"
do
  case $i in
    -d|--devel)
    DEVEL=true
    shift
    ;;
    -u|--update)
    UPDATE=true
    shift
    ;;
    -n|--no-update)
    NO_UPDATE=true
    shift
    ;;
    -bu|--bundle)
    BUNDLE=true
    shift
    ;;
    -c|--clean)
    CLEAN=true
    shift
    ;;
    -b=*|--branch=*)
    BRANCH="${i#*=}"
    shift
    ;;
    -b|--build)
    BUILD=true
    shift
    ;;
    --installer)
    INSTALLER=true
    BRANCH="stable"
    shift
    ;;
    --use-remote)
    USE_REMOTE=true
    shift
    ;;
    --repo-commit-subject=*)
    COMMIT_SUBJECT="${i#*=}"
    shift
    ;;
    --check)
    CHECK=true
    shift
    ;;
    --repo-commit-body=*)
    COMMIT_BODY="${i#*=}"
    shift
    ;;
    --gst-version=*)
    GST_VERSION="${i#*=}"
    shift
    ;;
    --gpg-sign=*)
    GPG_KEY="${i#*=}"
    shift
    ;;
    --generate-static-deltas)
    GENERATE_STATIC_DELTAS="--generate-static-deltas"
    shift
    ;;
  esac
done

if [ "$1" == "--help" ]
then
    echo "$HELP"
    exit 0
fi

# ------------------------------------------- #

flatpak remote-add --help | grep "\-\-from" > /dev/null 2>&1
if [ ! $? -eq 0 ]
then
  printf "$RED \nYou need to install flatpak >= 0.6.4 to be able to use the '$0' script.

You can find some informations about how to install it for your distribution at:

* http://flatpak.org/ $NC\n\n\n"

  if [ -n "$INSTALLER" ]
  then
    printf "\n\nYou can now exit that terminal."
    read
  fi
  exit 1
fi

# ------------------------------------------- #

# Computation of actual variable values
APPLICATION_REPO_NAME=`flatpak remote-list --user -d | grep "$APPLICATION_FLATPAK_REPO" | awk '{ print $1 }'`
flatpak remote-list --user | grep $APPLICATION_DEFAULT_REPO_NAME > /dev/null 2>&1
res=$?
# Update remote URL if needed
if [ $res != 0 ] && [ -n "$APPLICATION_REPO_NAME" ]
then
  echo "-> Setting $APPLICATION_DEFAULT_REPO_NAME URL to $APPLICATION_FLATPAK_REPO"
  flatpak remote-modify --user $APPLICATION_DEFAULT_REPO_NAME --url=$APPLICATION_FLATPAK_REPO
fi

APPLICATION_REPO_NAME=${APPLICATION_REPO_NAME:-$APPLICATION_DEFAULT_REPO_NAME}
SCRIPTDIR="$( cd "$( dirname "$(readlink -f ${BASH_SOURCE[0]})"  )" && pwd  )"

SDK_REPO_NAME=`flatpak remote-list --user -d | grep "$SDK_REPO" | awk '{ print $1 }'`
SDK_REPO_NAME=${SDK_REPO_NAME:-$SDK_DEFAULT_REPO_NAME}

REPO=$FLATPAK_ENVPATH/flatpak-repos/$APPLICATION_NAME

SDK_INSTALLED=`flatpak list --runtime -d | grep "$SDK_NAME/.*/$SDK_VERSION"`
SDK_LOCAL_INSTALLED=`flatpak list --runtime -d | grep "$SDK_NAME.Locale/.*/$SDK_VERSION"`

RUNTIME_INSTALLED=`flatpak list --runtime -d | grep "$RUNTIME_NAME/.*/$SDK_VERSION"`
RUNTIME_LOCAL_INSTALLED=`flatpak list --runtime -d | grep "$RUNTIME_NAME.Locale/.*/$SDK_VERSION"`
APP_INSTALLED=`flatpak list -d | grep "$APPLICATION_REF_NAME/.*/$BRANCH"`

if [ -n "$BUNDLE" ]
then
  BUILD=true
  DEVEL=true
fi

if [ -n "$BUILD" ]
then
  which flatpak-builder > /dev/null 2>&1
  if [ ! $? -eq 0 ]
  then
    echo "You need to install flatpak-builder to use the $0 script for development.
"
    exit 1
  fi
  DEVEL=true
fi

if [ -z "$DEVEL" ] && [ -z "$NO_UPDATE" ]
then
  UPDATE=true

  if [ -n "$*" ]
  then
    echo "Unknown arguments: $*"
    echo ""
    echo "$HELP"

    exit 1
  fi

  if [ -n "$RUNTIME_INSTALLED" ]
  then
    printf "$GREEN\n==========\nUpdating $APPLICATION_NAME \n==========$NC\n\n"
  else
    printf "$GREEN\n==========\nInstalling $APPLICATION_NAME \n==========$NC\n\n"
  fi
fi

function run_in_sandbox {
  flatpak build --socket=x11 --socket=session-bus --socket=pulseaudio \
  --share=network \
  --env=GST_PLUGIN_SYSTEM_PATH= \
  --env=GST_CHECKS=$GST_CHECKS \
  --env=GST_PRESET_PATH=/app/share/gstreamer-1.0/presets/:/app/share/pitivi/gstpresets/:$GST_PRESET_PATH \
  --env=GST_ENCODING_TARGET_PATH=/app/share/pitivi/gstpresets/:$GST_ENCODING_TARGET_PATH \
  --env=GST_DEBUG=$GST_DEBUG \
  --env=GST_PLUGIN_SYSTEM_PATH= \
  --env=GST_VALIDATE=$GST_VALIDATE \
  --env=GST_VALIDATE_LAUNCHER_DEBUG=$GST_VALIDATE_LAUNCHER_DEBUG \
  --env=PITIVI_DEBUG=$PITIVI_DEBUG \
  --env=PITIVI_DEVELOPMENT=1 \
  --env=DISPLAY=$DISPLAY \
  --env=GST_DEBUG_DUMP_DOT_DIR=$GST_DEBUG_DUMP_DOT_DIR \
  $PREFIX $SCRIPTDIR/enter-env "$@" || exit 1
}

function build_local_repo {
  echo "-> Building $APPLICATION_NAME from current repository"
  cd $APPLICATION_REPOSITORY
  run_in_sandbox "./configure --prefix=/app --libdir=lib" || exit 1
  run_in_sandbox make || exit 1
}

# Install needed runtimes
if [ -n "$DEVEL" ]
then
  if [ -z "$SDK_INSTALLED" ]
  then
    echo "-> Installing $SDK_NAME $SDK_VERSION"
    TEMPFILE=$(mktemp)
    echo "-> Adding repository '$SDK_REPO_NAME' from file: $SDK_REPO_FILE"
    curl $SDK_REPO_FILE -Sso $TEMPFILE || exit 1
    flatpak remote-add --user --from=$TEMPFILE $SDK_REPO_NAME > /dev/null 2>&1
    flatpak install --user $SDK_REPO_NAME $SDK_NAME $SDK_VERSION || exit 1
  fi

  if [ -z "$SDK_LOCAL_INSTALLED" ]
  then
    echo "-> Installing $SDK_NAME.Locale"
    $flatpak install --user $SDK_REPO_NAME $SDK_NAME.Locale $SDK_VERSION || exit 1
  fi
fi

if [ -z "$RUNTIME_INSTALLED" ]
then
  TEMPFILE=$(mktemp)
  echo "-> Adding repository $SDK_REPO_NAME from file: $SDK_REPO_FILE"
  curl $SDK_REPO_FILE -Sso $TEMPFILE || exit 1
  flatpak remote-add --user --from=$TEMPFILE $SDK_REPO_NAME > /dev/null 2>&1

  echo "-> Installing $RUNTIME_NAME $SDK_VERSION $RUNTIME_INSTALLED"
  flatpak install --user $SDK_REPO_NAME $RUNTIME_NAME $SDK_VERSION || exit 1
fi
if [ -z "$RUNTIME_LOCAL_INSTALLED" ]
then
  echo "-> Installing $RUNTIME_NAME.Locale"
  flatpak install --user $SDK_REPO_NAME $RUNTIME_NAME.Locale $SDK_VERSION || exit 1
fi

# Update runtimes if needed
if [ -n "$UPDATE" ]
then
  echo "-> Updating $RUNTIME_NAME $SDK_VERSION"
  flatpak update --user $RUNTIME_NAME $SDK_VERSION || exit 1

  echo "-> Updating $RUNTIME_NAME.Locale"
  flatpak update --user $RUNTIME_NAME.Locale $SDK_VERSION || exit 1

  if [ -n "$DEVEL" ]
  then
    echo "-> Updating $SDK_NAME $SDK_VERSION"
    flatpak update --user $SDK_NAME $SDK_VERSION || exit 1

    echo "-> Updating $SDK_NAME.Locale $SDK_VERSION"
    flatpak update --user $SDK_NAME.Locale $SDK_VERSION || exit 1
  fi
fi

# Not using remote repo and not bundling
if [ -n "$BUILD" ] && [ -z "$BUNDLE" ]
then
  cd $APPLICATION_REPOSITORY
  # Either a branch name or "HEAD".
  DEVELOPMENT_BRANCHNAME=`git rev-parse --abbrev-ref HEAD`
  cd - > /dev/null
  APP_BUILD_NAME="$APPLICATION_NAME-$DEVELOPMENT_BRANCHNAME"
  LOCAL_REPOS_PATH=$FLATPAK_ENVPATH
else
  DEVELOPMENT_BRANCHNAME=${BRANCH:-master}
  APP_BUILD_NAME=$APPLICATION_NAME
  LOCAL_REPOS_PATH=/nowhere/really
fi

if [ -n "$BUNDLE" ]
then
  PREFIX="$FLATPAK_ENVPATH/$APP_BUILD_NAME-prefix/"
else
  PREFIX=$FLATPAK_ENVPATH/prefix
fi

if [ -n "$CLEAN" ]
then
  echo "Cleaning environment..."

  echo "-> Removing $PREFIX"
  rm -Rf $PREFIX
fi

if [ -z $DEVEL ] || [ -z $BUILD ]
then
   TEMPFILE=$(mktemp)

   echo "-> Adding repository $APPLICATION_REPO_NAME from file: $APPLICATION_FLATPAK_REPO_FILE"
   curl $APPLICATION_FLATPAK_REPO_FILE -Sso $TEMPFILE || exit 1
   flatpak remote-add --user --from=$TEMPFILE $APPLICATION_REPO_NAME > /dev/null 2>&1

   if [ -z "$APP_INSTALLED" ]
   then
     echo "Installing $APPLICATION_REF_NAME $BRANCH..."

     flatpak install --user $APPLICATION_REPO_NAME $APPLICATION_REF_NAME $BRANCH
   fi

   if [ -n "$UPDATE" ]
   then
     echo "-> Updating $APPLICATION_REF_NAME $BRANCH..."

     flatpak update --user $APPLICATION_REF_NAME $BRANCH
   fi
fi

if [ -n "$DEVEL" ]
then
  if [ -z $BUILD ]
  then
    if [ -z "$APP_INSTALLED" ] && [ -z "$USE_REMOTE" ]
    then
      build_local_repo
    fi

    echo "=============================="
    echo "Entering prebuilt environment "
    echo "=============================="

    flatpak run --branch=$BRANCH -d --command=$SCRIPTDIR/enter-env $APPLICATION_REF_NAME
    exit $?
  fi

  if [ -n $BUILD ] && [ ! -f $PREFIX/metadata ]
  then
    UPDATE=true
    echo "Updating env $PREFIX"
  fi

  if [ -n "$UPDATE" ]
  then
    # Update values in the json template
    JSON=$SCRIPTDIR/$APP_BUILD_NAME.json
    $SCRIPTDIR/json-template-expander $SCRIPTDIR/$APPLICATION_NAME.template.json $JSON $LOCAL_REPOS_PATH $GST_VERSION $BRANCH

    echo "-> Removing prefix $PREFIX"
    rm -Rf $PREFIX

    FLATPAK_BUILD_OPTIONS=""
    if [ -z $BUNDLE ]
    then
      FLATPAK_BUILD_OPTIONS=" $FLATPAK_BUILD_OPTIONS --build-only"
    fi

    echo "-> Building $APPLICATION_NAME $DEVELOPMENT_BRANCHNAME from $JSON (options: $FLATPAK_BUILD_OPTIONS)"
    cd $SCRIPTDIR
    echo "Building with: flatpak-builder $FLATPAK_BUILD_OPTIONS $PREFIX $JSON"
    flatpak-builder --ccache $FLATPAK_BUILD_OPTIONS $PREFIX $JSON || exit 1

    if [ -z $BUNDLE ] || [ -n "$CHECK" ]
    then
      build_local_repo
    fi
  fi

  # Launch development environment if we are not updating it and not creating a bundle
  if [ -z $BUNDLE ] && [ -z $UPDATE ] && [ -z $CHECK ]
  then
    run_in_sandbox "$@"
  fi

  if [ -n "$CHECK" ]
  then
    run_in_sandbox "./configure --prefix=/app --libdir=lib -Denable-xunit=true"

    echo "-> Running unit tests"
    run_in_sandbox "make check"
  fi
else
  flatpak run org.pitivi.Pitivi
fi


if [ -n "$BUNDLE" ]
then
  echo "-> Creating repository $REPO if needed"
  mkdir -p $REPO

  if [ -z "$COMMIT_SUBJECT" ]
  then
      COMMIT_SUBJECT="Updating $APPLICATION_REF_NAME"
  fi

  if [ -n "$GPG_KEY" ]
  then
      GPG="--gpg-sign=$GPG_KEY"
  fi

  echo "-> Exporting repo $REPO $DEVELOPMENT_BRANCHNAME (args: --body="$COMMIT_BODY" --subject="$COMMIT_SUBJECT")"
  flatpak build-export $GPG --body="$COMMIT_BODY" --subject="$COMMIT_SUBJECT" $REPO $PREFIX $DEVELOPMENT_BRANCHNAME || exit 1

  echo "Updating repo $REPO"
  flatpak build-update-repo $GENERATE_STATIC_DELTAS $REPO || exit 1

  echo "DONE!"
fi
