#!/usr/bin/env bash
#
# Common file for travis emulator scripts
#
#__version__=2.0.11

[[ "${BASH_SOURCE-}" == "$0" ]] && echo "You must source this script: \$ source $0" >&2 && exit 33
XRGI="^(.*\/|)conf\/.*sample$"

opts_travis() {
  # opts_travis(git-org/pkgname)
  [[ -n "$1" ]] && IFS="/" read REMOTEREPO x <<<"$1"
  [[ -z "$REMOTEREPO" ]] && REMOTEREPO="local"
  [[ -z $TRAVIS_REPO_SLUG ]] && export TRAVIS_REPO_SLUG=$REMOTEREPO/$PKGNAME
}

inherits_travis_opts() {
  # inherits_travis_opts(opts_enables app)
  # app: After_test,Distribution,Emulator,Nightly,Please,Test,Vem,pep8
  local e o opts opts2
  [[ -n "$1" ]] && e=$1
  declare -A A
  A[A]="jnqv"
  A[D]="CcDdFfnOoPqRv"
  A[E]="cdjmnqrv"
  A[N]="CKnOR"
  A[P]="cdfjmnOqruv"
  A[T]="BcKPpqrTv"
  A[V]="qv"
  A[8]="dnquv"
  if [[ -n "$2" ]]; then
    for o in B C c d F f K j m n O o P p q R r T u v; do
      if [[ ${A[$2]} =~ $o ]]; then
        if [ "$o" == "B" -a ${opt_debug:-0} -ne 0 ]; then
          opts="${opts}$B"
        elif [ "$o" == "C" -a "$opt_cpush" == "-$o" ]; then
          opts="${opts}$o"
        elif [ "$o" == "d" -a ${opt_diff:-0} -gt 0 ]; then
          opts="${opts}$o"
        elif [ "$o" == "F" -a "$opt_cpush" == "-$o" ]; then
          opts="${opts}$o"
        elif [ "$o" == "f" -a ${opt_force:-0} -gt 0 ]; then
          opts="${opts}$o"
        elif [ "$o" == "j" -a ${opt_dprj:-0} -gt 0 ]; then
          opts="${opts}$o"
        elif [ "$o" == "n" -a ${opt_dry_run:-0} -gt 0 ]; then
          opts="${opts}$o"
        elif [ "$o" == "o" ]; then
          [ -n "$opt_ids" ] && opts2="-o$opt_ids"
        elif [ "$o" == "P" -a "$opt_cpush" == "-$o" ]; then
          opts="${opts}$o"
        # elif [ "$o" == "p" -a "${opt_pyth:-0}" -gt 0 ]; then
        #   opts="${opts}$o"
        elif [ "$o" == "q" -a ${opt_verbose:-1} -eq 0 ]; then
          opts="${opts}$o"
        elif [ "$o" == "R" -a "$opt_cpush" == "-$o" ]; then
          opts="${opts}$o"
        elif [ "$o" == "r" -a ${opt_r:-0} -eq 1 ]; then
          opts="${opts}$o"
        elif [ "$o" == "u" -a ${opt_uop:-0} -eq 1 ]; then
          opts="${opts}$o"
        elif [[ $o == "v" ]]; then
          [[ ${opt_verbose:-0} -ne 0 || $e =~ $o ]] && opts="${opts}$o"
          [[ ${opt_verbose:-0} -gt 1 ]] && opts="${opts}$o"
          [[ ${opt_verbose:-0} -gt 2 ]] && opts="${opts}$o"
          [[ ${opt_verbose:-0} -gt 3 ]] && opts="${opts}$o"
        elif [[ $e =~ $o ]]; then
          opts="${opts}$o"
        fi
      fi
    done
  fi

  if [ "$2" == "T" ]; then
    if [[ $e =~ [K] ]]; then
      export BASH_CHECK="1"
    fi
    if [[ $e =~ [PK] ]]; then
      export LINT_CHECK="1"
    fi
    if [[ $e =~ T ]]; then
      export TEST_CHECK="1"
    fi
    if [[ $e =~ n ]]; then
      if [ ${opt_dry_run:-0} -gt 0 ]; then
        export MQT_DRY_RUN="1"
      fi
    fi
    if [[ $e =~ q ]]; then
      if [ ${opt_verbose:-0} -eq 0 ]; then
        export MQT_VERBOSE_MODE="0"
      fi
    fi
    if [[ $e =~ v ]]; then
      if [ ${opt_verbose:-0} -gt 0 ]; then
        export MQT_VERBOSE_MODE="1"
      fi
    fi
  fi
  [[ -n "$opts" ]] && opts="-${opts}"
  [[ -n "$opts2" ]] && opts="${opts} ${opts2}"
  echo "$opts"
}

get_value_from_file() {
  # get_value_from_file(file value [sep])
  local x=$(basename $1)
  local n r s=$3
  [[ -z "$s" ]] && s="="
  if [ "$x" == "setup.py" ]; then
    if [ "$2" == "name" ]; then
      r=$(grep "[^a-zA-Z0-9_][\"']*$2[\"']* *$s" $1 2>/dev/null | awk -F"$s" '{print $2}' | tr -d "\"', \r\n")
    else
      r=$(grep "^ *[\"']*$2[\"']* *$s" $1 2>/dev/null | awk -F"$s" '{print $2}' | tr -d "\"'\r\n")
      [ "${r: -1}" == "," ] && r="${r:0:-1}"
    fi
  fi
  echo $r
}

init_travis() {
  local r x
  TRAVIS_ENV=virtualenv
  TRAVIS_ENVOPTS=$(get_cfg_value "" "virtualenv_opts")
  ## DEPRECATED, TODO: inherits_travis_opts()
  if [ ${opt_dry_run:-0} -gt 0 ]; then
    opts_dry_run=-n
  else
    opts_dry_run=
  fi
  ## DEPRECATED, TODO: inherits_travis_opts()
  if [ ${opt_upd:-0} -gt 0 ]; then
    opts_upd=-u
  else
    opts_upd=
  fi
  x=$(get_cfg_value "" "loglevel")
  if [ ${x:-1} -ne -1 ]; then
    opt_verbose=$x
  fi
  if [ ${opt_verbose:-0} -eq -1 ]; then
    if [[ -t 0 || -p /dev/stdin ]]; then
      opt_verbose=0
    else
      opt_verbose=1
    fi
  fi
  if [ ${opt_verbose:-0} -ge 0 ]; then
    opts_verbose=-v
    export FLOG_ECHO=echo
  else
    opts_verbose=
    export FLOG_ECHO=
  fi
  if [[ "$PRJNAME" == "Odoo" ]]; then
    [[ -z $REPOSNAME ]] && REPOSNAME=$(build_odoo_param REPOS ".")
    BRANCH=$(build_odoo_param FULLVER ".")
    SETUP=$MANIFEST
  fi
  # TODO>Deprecated
  if [[ -z "$TOOLS_PATH" ]]; then
    TOOLS_PATH=$(readlink -f $ODOO_ROOT/tools/zerobug/_travis)
    [[ ! -d $TOOLS_PATH ]] && TOOLS_PATH=$(find $HOME_DEVEL -type d -name _travis | head -n1)
  fi
}

revaluate_travis() {
  PRJNAME=
  REPOSNAME=
  PRJPATH=
  PGKNAME=
  PKGPATH=
  init_travis
}

get_dbuser() {
  # get_dbuser(suffix)
  local u x
  [[ -n $1 ]] && x="$1"
  [[ -z $x ]] && x=$(build_odoo_param MAJVER $BRANCH)
  for u in $USER odoo openerp postgresql; do
    if [[ -n "$x" ]]; then
      psql -U$u$x -l &>/dev/null
      if [[ $? -eq 0 ]]; then
        echo "$u$x"
        break
      fi
    fi
    psql -U$u -l &>/dev/null
    if [[ $? -eq 0 ]]; then
      echo "$u"
      break
    fi
  done
}

drop_test_db() {
  if [[ "$PRJNAME" == "Odoo" ]]; then
    [[ -n $PGUSER ]] || PGUSER=$USER
    [[ -n $MQT_TEMPLATE_DB ]] || MQT_TEMPLATE_DB="template_odoo"
    [[ -n $MQT_TEST_DB ]] || MQT_TEST_DB="test_odoo"
    pg_db_active -wa "$MQT_TEMPLATE_DB" && dropdb -U$PGUSER \"$MQT_TEMPLATE_DB\" --if-exists &>/dev/null
    c=$(pg_db_active -c "$MQT_TEMPLATE_DB")
    [[ $c -ne 0 ]] && echo "FATAL! There are $c other sessions using the database \"$MQT_TEMPLATE_DB\""
    pg_db_active -wa "$MQT_TEST_DB" && dropdb -U$PGUSER "$MQT_TEST_DB" --if-exists &>/dev/null
    [[ $c -ne 0 ]] && echo "FATAL! There are $c other sessions using the database \"$MQT_TEST_DB\""
  fi
}

custom_env() {
  # custom_env(VENV pyver)
  cd $1
  sed -i -e 's:VIRTUAL_ENV=.*:VIRTUAL_ENV="\$(readlink -f \$(dirname \$(readlink -f \$BASH_SOURCE))/..)":g' $PWD/bin/activate
  if $(grep -q "^export HOME=" $PWD/bin/activate); then
    sed -i -e 's|^export HOME=.*|export HOME="\$VIRTUAL_ENV"|g' $PWD/bin/activate
    # sed -i -e "s|^#.*/bin/python|#\!$PWD/bin/python|g" $PWD/bin/python-config
  else
    sed -ri "/deactivate *\(\) *\{/a\    export HOME=\$(grep \$USER /etc/passwd|awk -F: '{print \$6}')" $PWD/bin/activate
    [ "$SYSTEM_SITE_PACKAGES" != "true" -a -n "$2" ] && echo "[ -f /usr/bin/pip$2 -a ! -f \$VIRTUAL_ENV/bin/pip ] && ln -s /usr/bin/pip$2 \$VIRTUAL_ENV/bin/pip" >>$PWD/bin/activate
    echo "for f in \$VIRTUAL_ENV/bin/*;do" >>$PWD/bin/activate
    echo "    [ -x \$f ] && sed -i -e \"s|^#\!.*/bin/python|#\!\$VIRTUAL_ENV/bin/python|\" \$f" >>$PWD/bin/activate
    echo "done" >>$PWD/bin/activate
    echo "export HOME=\"\$VIRTUAL_ENV\"" >>$PWD/bin/activate
    # [[ "$SYSTEM_SITE_PACKAGES" == "true" ]] && echo "[ -d $HOME/tools ] && export PYTHONPATH=$HOME/tools">>$PWD/bin/activate
    # sed -i -e "s:^#\!*/bin/python:#!$PWD/bin/python:g" $PWD/bin/python-config
  fi
  sed -i -e 's|PATH="\$VIRTUAL_ENV/bin:\$PATH"|PATH="\$VIRTUAL_ENV/.local/bin:\$VIRTUAL_ENV/bin:\$PATH"|g' $PWD/bin/activate
  if [[ "$SYSTEM_SITE_PACKAGES" == "true" ]]; then
    if [[ -d $PWD/.local/lib/python$2/site-packages ]]; then
      echo -e "import site\nsite.addsitedir('$PWD/.local/lib/python$2/site-packages')\nsite.addsitedir('/usr/lib/python$2/site-packages')\nsite.addsitedir('/usr/lib64/python$2/site-packages')\n" >$PWD/lib/python$2/site-packages/sitecustomize.py
    else
      echo -e "import site\nsite.addsitedir('/usr/lib/python$2/site-packages')\nsite.addsitedir('/usr/lib64/python$2/site-packages')\n" >$PWD/lib/python$2/site-packages/sitecustomize.py
    fi
  elif [[ -d $PWD/.local/lib/python$2/site-packages ]]; then
    echo -e "import site\nsite.addsitedir('$PWD/.local/lib/python$2/site-packages')\n" >$PWD/lib/python$2/site-packages/sitecustomize.py
  fi
}

uname() {
    local x UNAME
    UNAME=$(which uname)
    [[ -x $TRAVIS_HOME/bin/greadlink ]] && echo "Darwin" || $UNAME "$@"
}

create_virtual_env() {
  local f opts p sts=0 t x xp1 xp2
  [[ -z ${Z0_STACK:+_} ]] && export Z0_STACK=0
  ((Z0_STACK=Z0_STACK+2))
  # Avoid conflict during tests
  ls $HOME/.local/bin/* &>/dev/null && run_traced "rm -fR $HOME/.local/bin/*"
  unset TOOLS_PATH
  init_travis
  export TRAVIS_BRANCH=$(git branch --list|grep "^\* "|cut -d" " -f2|head -n1|tr -d "\n")
  [[ -z "$HOME_DEVEL" ]] && echo "Zeroincombenze® tools not found!" && exit 1
  drop_test_db
  export TRAVIS_SAVED_HOME=$HOME
  export TRAVIS_SAVED_HOME_DEVEL=$HOME_DEVEL
  [[ -z $ODOO_ROOT ]] && ODOO_ROOT=$(readlink -f $HOME_DEVEL/..)
  export SAVED_ODOO_ROOT=$ODOO_ROOT
  if [[ $HOME =~ ^/(home|opt)/travis && -d $HOME/virtualenv ]]; then
    export TRAVIS=true
    export TRAVIS_HOME=$HOME/virtualenv
    [[ -d $HOME/../odoo/tools ]] && TRAVIS_SAVED_HOME=$(readlink -f $HOME/../odoo)
  else
    [[ $opt_full -ne 0 || $opt_cache -eq 0 ]] && export TRAVIS=emulate || export TRAVIS=false
    export TRAVIS_HOME=$(readlink -f $HOME/VENV_$$)
  fi
  HOME=$TRAVIS_HOME
  TRAVIS_ENVOPTS="$TRAVIS_ENVOPTS -p $(which python$TRAVIS_PYTHON_VERSION)"
  [[ $SYSTEM_SITE_PACKAGES == "true" ]] && TRAVIS_ENVOPTS="$TRAVIS_ENVOPTS --system-site-packages"
  [[ $TRAVIS_DEBUG_MODE -gt 2 ]] && VENVOPTS="-vD" || VENVOPTS="-D"
  [[ $SYSTEM_SITE_PACKAGES == "true" && -n $opt_loc ]] && VENVOPTS="-Dl${opt_loc}"
  [[ $SYSTEM_SITE_PACKAGES != "true" && -n $opt_loc ]] && VENVOPTS="-DIl${opt_loc}"
  [[ $SYSTEM_SITE_PACKAGES != "true" && -z $opt_loc ]] && VENVOPTS="-DI"
  hash -r
  [[ -n $BRANCH ]] && TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$BRANCH || TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$TRAVIS_PYTHON_VERSION
  xp=0
  [[ ! -d $TRAVIS_SRC_VME || $opt_force -ne 0 ]] && xp=1
  [[ $xp -eq 0 && -d $TRAVIS_SRC_VME ]] && vem $TRAVIS_SRC_VME exec "flake8 --version &>/dev/null" || xp=1
  [[ $xp -eq 0 && -d $TRAVIS_SRC_VME ]] && vem $TRAVIS_SRC_VME exec "pylint --version &>/dev/null" || xp=1
  x=$((($(echo "$TRAVIS_PYTHON_VERSION" | sed -E "s/\./*/"))))
  x=$((750000000/x))
  [[ $xp -eq 0 && opt_keep -eq 0 ]] && xp=$(($(date "+%s") - $(stat -c%Y $TRAVIS_SRC_VME) > $x))
  [[ $TRAVIS_DEBUG_MODE -ge 2 && $xp -ne 0 && -d $TRAVIS_SRC_VME ]] && echo "(\$(date '+%s'=$(date "+%s")) - \$(stat -c%Y $TRAVIS_SRC_VME)=$(stat -c%Y $TRAVIS_SRC_VME))) > $x"
  if [[ $xp -ne 0 ]]; then
    echo -e "\n\n${RED}Cached virtual environment $TRAVIS_SRC_VME not found or expired!${CLR}"
    echo -e "Now virtual environment $TRAVIS_SRC_VME will be (re)created."
    run_traced "vem create $VENVOPTS $TRAVIS_SRC_VME -DI -p$TRAVIS_PYTHON_VERSION -fq"
    echo -e "\n\n"
    vem $TRAVIS_SRC_VME update flake8    # STRANGE ERROR! WORKAROUND!
    [[ -d $TRAVIS_HOME ]] && rm -fR $TRAVIS_HOME    # STRANGE ERROR! WORKAROUND!
  fi
  if [[ $TRAVIS == "true" || -d $TRAVIS_HOME ]]; then
    true
  elif [[ $opt_full -eq 0 && ${opt_cache:-0} -ne 0 && -n "$TRAVIS_PYTHON_VERSION" ]]; then
    [[ -d $SAVED_ODOO_ROOT ]] || mkdir $SAVED_ODOO_ROOT
    if [[ "$PRJNAME" == "Odoo" && -d $SAVED_ODOO_ROOT/VME/VME$BRANCH ]]; then
      opt_keepE=0
      TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$BRANCH
      opts=$(inherits_travis_opts "" "V")
      [[ $TRAVIS == "true" ]] || opts="$opts -f"
      run_traced "vem cp $VENVOPTS $opts $TRAVIS_SRC_VME $TRAVIS_HOME"
      sts=$?
    elif [[ -d "$SAVED_ODOO_ROOT/VME/VME$TRAVIS_PYTHON_VERSION" ]]; then
      opt_keepE=0
      TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$TRAVIS_PYTHON_VERSION
      opts=$(inherits_travis_opts "" "V")
      [[ $TRAVIS == "true" ]] || opts="$opts -f"
      run_traced "vem cp $VENVOPTS $opts $TRAVIS_SRC_VME $TRAVIS_HOME"
      sts=$?
    else
      if [[ "$PRJNAME" == "Odoo" && -n "$VERSION" ]]; then
        TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$VERSION
        opts=$(inherits_travis_opts "" "V")
        [[ $TRAVIS == "true" ]] || opts="$opts -f"
        opts="$opts -q"
        run_traced "vem create $VENVOPTS $TRAVIS_HOME $opts -p$TRAVIS_PYTHON_VERSION -O$VERSION"
        sts=$?
      else
        TRAVIS_SRC_VME=$SAVED_ODOO_ROOT/VME/VME$TRAVIS_PYTHON_VERSION
        opts=$(inherits_travis_opts "" "V")
        [[ $TRAVIS == "true" ]] || opts="$opts -f"
        opts="$opts -q"
        run_traced "vem create $VENVOPTS $TRAVIS_HOME $opts -p$TRAVIS_PYTHON_VERSION"
        sts=$?
      fi
      opts=$(inherits_travis_opts "" "V")
      [[ $TRAVIS == "true" ]] || opts="$opts -f"
      [[ $sts -ne 0 || $opt_keepE -eq 0 ]] || run_traced "vem cp $VENVOPTS $opts $TRAVIS_HOME $TRAVIS_SRC_VME"
    fi
  else
    echo "\$ virtualenv -q $TRAVIS_ENVOPTS $TRAVIS_HOME"
    [[ ${opt_dry_run:-0} -ne 0 ]] || virtualenv -q $TRAVIS_ENVOPTS $TRAVIS_HOME
    sts=$?
  fi
  [[ $sts -ne 0 ]] && return

  run_traced "source $TRAVIS_HOME/bin/activate"
  [[ ${opt_keep:-0} -ne 0 ]] && run_traced "export ODOO_COMMIT_TEST=\"1\""
  set_pybin $TRAVIS_PYTHON_VERSION
  if [[ $opt_devpkg -ne 0 ]]; then
    # -Z: Install unstable packages to run them when needed
    for p in $(get_cfg_value "" "LOCAL_PKGS"); do
        # Use unstable version
        [[ $p =~ (python-plus|z0bug-odoo) ]] && p="${p//-/_}"
        [[ -f $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/scripts/setup.py ]] && \
          run_traced "$PIP install -qU $TRAVIS_SAVED_HOME_DEVEL/pypi/$p"
    done
  fi
  [[ -n $NVM_DIR && -f $NVM_DIR/nvm.sh ]] && source $NVM_DIR/nvm.sh
  if [ $opt_cache -ne 0 -a "$TRAVIS" == "false" -a -d $HOME/lib/python$TRAVIS_PYTHON_VERSION/site-packages ]; then
    export PYPI_CACHED=$HOME/lib/python$TRAVIS_PYTHON_VERSION/site-packages/
  fi
  export PKGNAME=$(basename $TRAVIS_SAVED_PKGPATH)
  export TRAVIS_REPO_SLUG=$REMOTEREPO/$PKGNAME
  [[ ${opt_dry_run:-0} -eq 0 ]] && mkdir -p $TRAVIS_HOME/build
  [[ ${opt_dry_run:-0} -eq 0 ]] && mkdir -p $TRAVIS_HOME/build/$REMOTEREPO
  # Compatibility with OCA test
  [[ -d $TRAVIS_HOME/maintainer-quality-tools ]] && rm -fR -d $TRAVIS_HOME/maintainer-quality-tools
  export TRAVIS_BUILD_DIR="$TRAVIS_HOME/build/$TRAVIS_REPO_SLUG"
  echo "Download testing repository ..."
  mkdir -p $TRAVIS_BUILD_DIR
  x=$(readlink -f $TRAVIS_BUILD_DIR/..)
  run_traced "cp -R $TRAVIS_SAVED_PKGPATH/ $x/"
  # [[ -f $TRAVIS_SAVED_PKGPATH/setup.py ]] && run_traced "cp $TRAVIS_SAVED_PKGPATH/setup.py $x/"
  [[ -f $TRAVIS_SAVED_PKGPATH/../setup.py ]] && run_traced "cp $TRAVIS_SAVED_PKGPATH/../setup.py $TRAVIS_BUILD_DIR/"
  if [[ ${opt_devpkg:-0} -ne 0 && "$TRAVIS_REPO_SLUG" == "local/tools" ]]; then
    git_clone "https://github.com/zeroincombenze/tools.git"
    [[ $HOME_DEVEL =~ /devel$ ]] && run_traced "cp $TRAVIS_SAVED_HOME_DEVEL/pypi/tools/install_tools.sh $TRAVIS_BUILD_DIR/ -o"
  fi
  [[ $PWD != $TRAVIS_BUILD_DIR ]] && run_traced "cd $TRAVIS_BUILD_DIR"
  get_pypi_param "ALL"
  if [[ -n "$opt_pybrk" ]]; then
    IFS=":" read f t <<<"$opt_pybrk"
    [[ $f =~ ^\. ]] && x=$(readlink -f $TRAVIS_BUILD_DIR/$f) || x=$(find $TRAVIS_BUILD_DIR -name $f)
    [[ -z "$x" ]] && echo "File $f not found!" && exit 1
    cp $x $x.bak
    cat <<EOF | python
with open('$x', 'r') as fd:
    lines = fd.read().split('\n')
    line = lines[$t - 1]
    i = 0
    while i < len(line) and line[i] == ' ':
        i += 1
    line = '%s%s' % (line[:i], 'import pdb; pdb.set_trace(); ')
    lines.insert($t - 1, line)
with open('$x', 'w') as fd:
    fd.write('\n'.join(lines))
EOF
  fi
  ((Z0_STACK=Z0_STACK-2))
}

drop_virtual_env() {
  [[ ${opt_virt:-0} -gt 0 ]] && run_traced "deactivate"
  [[ $TRAVIS == "true" ]] && export HOME=$(readlink -f $TRAVIS_HOME/..) || export HOME=$TRAVIS_SAVED_HOME
  [[ -n $TRAVIS_SAVED_HOME_DEVEL ]] && export HOME_DEVEL=$TRAVIS_SAVED_HOME_DEVEL
  [[ -n $SAVED_ODOO_ROOT ]] && export ODOO_ROOT=$SAVED_ODOO_ROOT
  hash -r
  unset TRAVIS_SAVED_HOME
  unset TRAVIS_SAVED_HOME_DEVEL
  unset SAVED_ODOO_ROOT
  cd $TRAVIS_SAVED_PKGPATH
  if [[ ${opt_keep:-0} -eq 0 ]]; then
    drop_test_db
    if [[ $TRAVIS != "true" ]]; then
      rm -fR $TRAVIS_HOME
      unset TRAVIS_HOME
      hash -r
    fi
  fi
  [[ ${opt_virt:-0} -gt 0 ]] && echo "HOME=$HOME" && echo "HOME_DEVEL=$HOME_DEVEL" && echo "ODOO_ROOT=$ODOO_ROOT" && echo "PWD=$PWD"
  TRAVIS_ENVOPTS=$(get_cfg_value "" "virtualenv_opts")
}

emulate_git_clone_OCB() {
  # emulate_git_clone_OCB(src tgt)
  local d f
  # local SAVE_COLOR=$PS_RUN_COLOR
  # export PS_RUN_COLOR="1;90;46"
  run_traced "mkdir -p $2/"
  valid="addons babel.cfg bin CONTRIBUTING.md COPYRIGHT debian doc gen_translations.sh gunicorn.conf.py LICENSE logging.json Makefile MANIFEST.in npybabel.py odoo odoo.py odoo-bin openerp openerp-cron-worker openerp-gevent openerp-server openerp-web openerp-web.cfg openerp-wsgi.py README.md requirements.txt server setup setup.cfg setup.py win32"
  for d in $1/*; do
    f=$(basename $d)
    if [[ " $valid " =~ " $f " ]]; then
      if [ -d $1/$f ]; then
        run_traced "cp -R $1/$f/ $2/"
      else
        run_traced "cp $1/$f $2"
      fi
    fi
  done
  # export PS_RUN_COLOR=$SAVE_COLOR
}

git_clone() {
  # emulate git clone
  local d x s t
  while [[ -n "$1" && "${1:0:1}" == "-" ]]; do
    shift
  done
  if [[ $1 == "https://github.com/zeroincombenze/tools.git" ]]; then
    if [[ -n "$2" ]]; then
      d=$(readlink -m $2/..)
    else
       d=$(readlink -m ./)
    fi
    [[ -z $SAVED_ODOO_ROOT ]] && SAVE_ODOO_ROOT=$(readlink -f $TRAVIS_SAVED_HOME_DEVEL/..)
    if [[ $opt_devpkg -ne 0 ]]; then
      x=${TRAVIS_REPO_SLUG#*/}
      for p in $(get_cfg_value "" "LOCAL_PKGS"); do
        # Load unstable version
        [[ $p =~ (python-plus|z0bug-odoo) ]] && p="${p//-/_}"
        [[ -f $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/setup.py && -d $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/$p ]] && \
          run_traced "mkdir -p $d/tools/$p/" && \
          run_traced "rsync -rlpgoW --delete $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/$p/ $d/tools/$p/" && \
          run_traced "cp $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/setup.py $d/tools/$p/"
          [[ -f $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/README.rst ]] && run_traced "cp $TRAVIS_SAVED_HOME_DEVEL/pypi/$p/README.rst $d/tools/$p/"
        s=$?; [ ${s-1} -eq 0 ] || echo "Internal error $s! Statement rsync $p failed!!"
      done
      for p in install_tools.sh odoo_template_tnl.xlsx; do
        [[ -d $TRAVIS_SAVED_HOME_DEVEL/pypi/tools/ ]] && \
          run_traced "cp $TRAVIS_SAVED_HOME_DEVEL/pypi/tools/$p $d/tools/$p"
      done
      for p in templates license_text tests; do
        [[ -d $TRAVIS_SAVED_HOME_DEVEL/pypi/tools/ ]] && \
          run_traced "cp -r $TRAVIS_SAVED_HOME_DEVEL/pypi/tools/$p $d/tools/"
      done
      true # FIX: return no error
    else
      run_traced "cp -R $SAVED_ODOO_ROOT/tools $d"
    fi
  fi
}

prepare_env_travis() {
  local action="$1"
  local v x
  if [[ $action =~ ^(force-lint|lint|force-test|test|force-test-multi|test-multi|force-testdeps|testdeps|force-translate|translate|emulate)$ ]]; then
    if [[ -n "$TOOLS_PATH" ]]; then
      if [ ${opt_r:-0} -gt 0 ]; then
        if [[ ! :$PATH: =~ :$TOOLS_PATH: ]]; then
          run_traced "export PATH=$TOOLS_PATH:$PATH"
        fi
      elif [ "$2" == "-r" ]; then
        if [[ ! :$PATH: =~ :$TOOLS_PATH: ]]; then
          run_traced "export PATH=$TOOLS_PATH:$PATH"
        fi
      fi
    fi
  fi
  NPM_CONFIG_PREFIX=$(get_cfg_value "" "NPM_CONFIG_PREFIX")
  export NPM_CONFIG_PREFIX=$NPM_CONFIG_PREFIX
  export BRANCH
  [[ -z "$VERSION" ]] && export VERSION=$BRANCH
  if [[ $action == "force-lint" ]]; then
    export LINT_CHECK="1"
    export TESTS="0"
    export TEST_DEPENDENCIES="0"
    export ODOO_TNLBOT="0"
  elif [[ $action =~ (force-test|force-test-multi) ]]; then
    export LINT_CHECK="0"
    export TESTS="1"
    export TEST_DEPENDENCIES="0"
    export ODOO_TNLBOT="0"
  elif [[ $action == "force-testdeps" ]]; then
    export LINT_CHECK="0"
    export TESTS="0"
    export TEST_DEPENDENCIES="1"
    export ODOO_TNLBOT="0"
  elif [[ $action == "force-translate" ]]; then
    export LINT_CHECK="0"
    export TESTS="0"
    export TEST_DEPENDENCIES="0"
    export ODOO_TNLBOT="1"
  fi
  [[ "$PRJNAME" == "Odoo" ]] && export ODOO_REPO=$REMOTEREPO/${PRJNAME,,}
  if [[ -n "$opt_dpath" ]]; then
    LGITPATH="$opt_dpath"
  elif [[ $PRJNAME == "Odoo" ]]; then
    if [[ -n "$opt_branch" ]]; then
      x=$(build_odoo_param PKGNAME ".")
      LGITPATH=$(build_odoo_param HOME "$opt_branch" "$REPOSNAME")
      [[ -n "$x" ]] && LGITPATH="$LGITPATH/$x"
    fi
  else
    [[ -n "$REPOSNAME" ]] && LGITPATH=$(get_cfg_value "" "${REPOSNAME}_distpath")
    [[ -z "$LGITPATH" ]] && LGITPATH=$(get_cfg_value "" "${PRJNAME}_distpath")
    [[ -z "$LGITPATH" ]] && LGITPATH=$(get_cfg_value "" "distpath")
  fi
  if [[ -n "$LGITPATH" ]]; then
    if [[ "$PRJNAME" == "Odoo" ]]; then
      export LGITPATH=$(expand_path "$LGITPATH")
    else
      local x="$(readlink -e $PWD/..)"
      local y=$(dirname $LGITPATH)
      if [[ "$PWD" == "$y" || "$x" == "$y" ]]; then
        export LGITPATH=$y
      else
        export LGITPATH=$(expand_path "$LGITPATH")
      fi
    fi
    if [[ "$LGITPATH" == "$PWD" ]]; then
      LGITPATH=
    fi
  fi
  export TOOLS_PATH
  export ODOO_SETUP
  export REPOSNAME
  export PRJNAME
  export PRJPATH
  export PKGPATH
  export PKGNAME
  export LGITPATH
}

check_4_travis() {
  if [[ -n "$PKGPATH" && ! -d "$PKGPATH" ]]; then
    echo "Invalid package path $PKGPATH"
    exit $STS_FAILED
  fi
}

conf_default() {
  [[ -z $(get_cfg_value "" "loglevel") ]] && CFG_set "loglevel" "-1"
  [[ -z $(get_cfg_value "" "RUN_travis_install_nightly") ]] && CFG_set "RUN_travis_install_nightly" "travis_install_nightly"
  [[ -z $(get_cfg_value "" "RUN_travis_run_tests") ]] && CFG_set "RUN_travis_run_tests" "travis_run_tests"
  [[ -z $(get_cfg_value "" "RUN_travis_after_tests_success") ]] && CFG_set "RUN_travis_after_tests_success" "travis_after_tests_success"
  [[ -z $(get_cfg_value "" "MQT_TEMPLATE_DB") ]] && CFG_set "MQT_TEMPLATE_DB" "template_odoo"
  [[ -z $(get_cfg_value "" "MQT_TEST_DB") ]] && CFG_set "MQT_TEST_DB" "test_odoo"
  [[ -z $(get_cfg_value "" "MQT_DBUSER") ]] && CFG_set "MQT_DBUSER" ""
  [[ -z $(get_cfg_value "" "UNBUFFER") ]] && CFG_set "UNBUFFER" "0"
  [[ -z $(get_cfg_value "" "ME_BOS") ]] && CFG_set "ME_BOS" "test_nightly .test_nightly.conf.sample"
  [[ -z $(get_cfg_value "" "Environment") ]] && CFG_set "Environment" "bash"
  [[ -z $(get_cfg_value "" "virtualenv_opts") ]] && CFG_set "virtualenv_opts" ""
  [[ -z $(get_cfg_value "" "NPM_CONFIG_PREFIX") ]] && CFG_set "NPM_CONFIG_PREFIX" "$HOME/.npm-global"
  [[ -z $(get_cfg_value "" "PYTHON_MATRIX") ]] && CFG_set "PYTHON_MATRIX" "(3.13|3.12|3.11|3.10|3.9|3.8|3.7|3.6|2.7)"
  [[ -z $(get_cfg_value "" "LOGDIR") ]] && CFG_set "LOGDIR" "$HOME/travis_log"
  # Test disabled by default: they are added to EXCLUDE paramEter
  # [[ -z $(get_cfg_value "" "GBL_EXCLUDE") ]] && CFG_set "GBL_EXCLUDE" "test_impex,test_ir_actions,test_lint,test_main_flows,test_search,test_user_has_group,test_mimetypes"
}

#
# [antoniov: 2022-08-06] TODO: remove early
#
a_append() {
  # a_append (key, values)::DEFPRM,DEFVAL
  # return:
  # key=="--new" && value=="" -> clean dictionary
  if [ "$1" == "--new" -a -z "$2" ]; then
    unset DEFPRM[*]
    unset DEFVAL[*]
    declare -g DEFPRM DEFVAL
    return
  fi
  if [ "$1" ]; then
    local l=${#DEFPRM[*]}
    DEFPRM[l]="$1"
    DEFVAL[l]="$2"
  fi
}

a_search() {
  # a_search (key)::DEFPRM,DEFVAL
  # return:value,sts
  local jy=0
  local p=""
  local sts=0
  while ((jy < ${#DEFPRM[*]})); do
    if [ "${DEFPRM[jy]:0:1}" == "^" ]; then
      if [[ $1 =~ ${DEFPRM[jy]} ]]; then
        p="${DEFVAL[jy]}"
        sts=1
        break
      fi
    elif [[ $1 == "${DEFPRM[jy]}" ]]; then
      p="${DEFVAL[jy]}"
      sts=1
      break
    fi
    ((jy++))
  done
  echo "$p"
  return $sts
}

matches1of() {
  # matches1of (filename, exclist)
  # return:true/false
  local x sts
  sts=1
  for x in $2; do
    [[ $1 =~ $x ]] && sts=0 && break
  done
  return $sts
}

robocopy_init() {
    # robocopy_init (prjname, PKGNAME)::DIST_CONF,TCONF,opt_fetch,opt_verbose
    a_append "--new"
    a_append "^.*\.egg-info$" ""
    if [ "$1" == "Odoo" ]; then
      a_append "^.*" "/"
    else
      a_append "setup.py" ""
      if [ "$2" == "OCB" ]; then
        local p=$(echo $PWD | grep --color=never -Eo "(v7|6.1|7.0|8.0|9.0|10.0|11.0|12.0|13.0|14.0|15.0|16.0)" | head -n1)
        if [ -n "$p" ]; then
          a_append "$p" "/"
        fi
      else
        a_append "$2" "/"
      fi
      a_append "conf" "/"
      if [ ${opt_fetch:-0} -eq 0 ]; then
        a_append "README.rst" "/"
        a_append "README.md" "/"
      fi
      a_append "^.*" ""
    fi
    local xx="$(get_cfg_value "" filedel) $(get_cfg_value "" fileignore)"
    local yy="$(get_cfg_value "" filediffignore)"
    XRGX=
    XLFS=
    XLDF=
    for x in $xx; do
      local x1="${x:0:1}"
      local l=
      let l=${#x}-1
      local x9="${x:l:1}"
      if [ "$x9" == "/" ]; then
        XRGX="$XRGX ^(.*\\/|)$x"
        XLFS="$XLFS --exclude=$x"
      elif [ "$x1" == "." -o "$x1" == "," -o "$x" == "~" ]; then
        XRGX="$XRGX ^.*\\$x\$"
        XLFS="$XLFS --exclude=*$x"
      else
        XRGX="$XRGX $x"
        XLFS="$XLFS --exclude=*$x*"
      fi
      XLDF="$XLDF -x '*$x'"
    done
    XXDF=
    for x in $yy; do
      local x1="${x:0:1}"
      local l=
      let l=${#x}-1
      local x9="${x:l:1}"
      if [ "$x9" == "/" ]; then
        XXDF="$XXDF ^(.*\\/|)$x"
      elif [ "$x1" == "." -o "$x" == "~" ]; then
        XXDF="$XXDF ^.*\\$x\$"
      else
        XXDF="$XXDF $x"
      fi
    done
}

robocopy() {
  # robocopy (srcfname, tgtpath, sshopt)::opt_dry_run,opts_dry_run,opt_verbose,XRGX,XRGI,XLFS
  # return:
  if [ -d "$1" ]; then
    local t="d"
    local ff=$1/
  else
    local t="f"
    local ff=$1
  fi
  local fn=$(basename $1)
  if $(matches1of "$ff" "$XRGI"); then
    local v=$(a_search "$fn")
  elif $(matches1of "$ff" "$XRGX"); then
    local v=
  else
    local v=$(a_search "$fn")
  fi
  if [[ $fn == "pypi" || "${v:0:1}" == "/" ]]; then
    if [[ ($fn == "pypi" || "$v" == "/") && "$t" == "d" ]]; then
      if [[ "${3:0:3}" == "ssh" ]]; then
        if [ ${opt_verbose:-0} -gt 0 ]; then
          local optrsync="-abvzhe"
        else
          local optrsync="-abzhe"
        fi
        if [[ ! "$3" == "ssh" && "${3:0:3}" == "ssh" ]]; then
          local optssh="${3:4}"
        else
          local optssh="$3"
        fi
        run_traced "rsync $opts_dry_run $optrsync \"$optssh\" $opts_upd --del --copy-links $XLFS $ff $2$v"
      else
        if [ ${opt_verbose:-0} -gt 0 ]; then
          local optrsync="-abv"
        else
          local optrsync="-ab"
        fi
        local optssh=""
        run_traced "rsync $opts_dry_run $optrsync $opts_upd --del --copy-links $XLFS $ff $2$v"
      fi
    else
      if [ "${3:0:3}" == "ssh" ]; then
        local optssh="${3:3}"
        run_traced "scp -Bp $optssh $ff $2"
      else
        if [ ! -d "$2" ]; then
          local v=
        fi
        diff -q $ff $2$v &>/dev/null
        if [ $? -ne 0 ]; then
          run_traced "cp -L $ff $2$v"
        fi
      fi
    fi
  fi
}

ant_rm_trap() {
  # wlog "... recover $1"
  local f1=$(readlink -f $1)
  if [ -n "$f1" -a -f "$f1" ]; then
    local lne=$(head -n1 $f1)
    if [ -n "$lne" -a "${lne:0:5}" == "trap " ]; then
      echo "... recover $f1"
      tail -n+2 $f1 >$f1.tmp
      mv -f $f1.tmp $f1
    fi
  fi
}

ant_add_trap() {
  echo "... analyzing $1"
  local f1=$(readlink -f $1)
  if [ -n "$f1" -a -f "$f1" ]; then
    ant_rm_trap "$f1"
    echo "trap \"echo [\$LINENO] \$BASH_SOURCE:\$BASH_COMMAND>>$FHIST\" DEBUG" >$f1.sh
    local line=
    while IFS=\~ read -r line || [ -n "$line" ]; do
      echo "$line" >>$f1.sh
      if [ "${line:0:1}" == "." ]; then
        local fn="${line:2}"
        local p="$(dirname $fn)"
        if [ "$p" == "." ]; then
          if [ "$(echo " $FL_2_TEST " | grep -v [[:space:]]$fn[[:space:]] 2>/dev/null)" ]; then
            FL_2_TEST="$FL_2_TEST $fn"
          fi
        fi
      fi
    done <"$f1"
    rm -f $FHIST
    chmod +x $f1.sh
    mv -f $f1.sh $f1
  fi
}

ant_erase() {
  local fn
  for fn in $(find . -type f -executable); do
    if [[ $fn =~ \.[a-zA-Z0-9_]{1,3} ]]; then
      if [ ${fn: -3} == ".sh" ]; then
        ant_rm_trap $fn
      fi
    else
      ant_rm_trap $fn
    fi
  done
}

set_executable() {
  local b cmd d excl f gx="" o p w XXXX x yy
  [[ -n "$1" ]] && d=$1 || d="."
  XXXX=$(get_cfg_value "" "filedel")
  [[ $PWD == "$HOME/tools" ]] && XXXX="$XXXX *_doc.txt setup.sh pythonhosted-*.zip __old_* __new_*"
  yy=$(get_cfg_value "" "fileignore")
  excl=""
  for x in $yy; do [[ ${x: -1} == "/" ]] && excl="$excl ${x:0: -1}"; done
  excl=${excl:1}
  [[ $opt_verbose -gt 1 ]] && echo "fileignore(conf)='$excl'"
  [[ -f ".gitmodules" ]] && \
    gx=$(cat .gitmodules | grep "^[[:space:]]*path" | sed -e "s/ =/=/g" -e "s/= /=/g" -e "s/^[[:space:]]*//g" | awk -F= '{print $2}'|tr "\n" "|")
  gx="(${gx}lib|git|__to_remove|tmp|node_modules|.cache)"
  [[ $opt_verbose -gt 1 ]] && echo "gitignore='$gx'"
  d="."
  cmd="find $d"
  [[ -d $d/addons && (-d $d/odoo || -d $d/openerp)]] && w=1 || w=0
  for f in $d/*; do
    b=$(basename $f)
    [[ $opt_verbose -gt 0 && $w -ne 0 && -d $f && -n "$gx" && ! $b =~ $gx && ! $b =~ (addons|debian|doc|egg-info|odoo|openerp) ]] && echo "Warning! Directory $f should be in .gitmodules"
    [[ -d $f && (-z "$gx" || (-n "$gx" && $b =~ $gx)) ]] && cmd="$cmd -not -path '$f/*'"
  done
  for f in $excl; do cmd="$cmd -not -path '*/$f/*'"; done
  o="-nowarn"
  [[ $opt_verbose -gt 0 ]] && x="-v +x" || x="+x"
  cmd="$cmd -type f"
  run_traced "$cmd -not -name '*.sh' -not -name '*.pyc' -not -perm /+x -exec grep -El '^#\! */.+' '{}' \;|xargs -I{} chmod $x {}"
  run_traced "$cmd \( -name '*.sh' -o -name '*.pyc' \) -not -perm /+x -exec chmod $x '{}' \;"
  run_traced "$cmd -not -name '*.js' -not -perm /+x -exec grep -El '#. *(/bin/|/usr/)' '{}' \;|xargs -I{} chmod $x {}"
}

#coverage() {
#  [[ -z $COVERAGE ]] && COVERAGE=$(which coverage 2>/dev/null)
#  if [[ $1 == "erase" ]]; then
#    mkdir -p $PKGPATH/cover
#    find . -name "*.tracehistory" -delete
#    find . -name "*,cover" -delete
#    find . -name ".coverage" -delete
#    # ant_erase
#  fi
#  if [[ -n $COVERAGE ]]; then
#    eval $COVERAGE "$@"
#  else
#    :
#  fi
#  return $?
#}

run_unvirt() {
  #run_unvirt (cmd)
  if [ ${opt_virt:-0} -eq 0 ]; then
    run_traced "$1"
  else
    :
  fi
  return $?
}

run_svr_test_exit() {
  if [ "$PRJNAME" == "Odoo" ]; then
    run_svr_test_rm_ln wep
  fi
}

run_server_test() {
  echo "======== Running server_test ========"
  run_svr_test_init
  run_svr_test_exit
  sts=$STS_FAILED
  return $sts
}

conf_default
