#!/usr/bin/env bash
# -*- coding: utf-8 -*-
#
# Odoo Library
# Common function to manage Odoo
# Most of directory examples refer to /opt/odoo/11.0/l10n-italy/l10n_it
# Most of directory examples refer to /opt/odoo/11.0/l10n-italy/l10n_it
# Item to process (+ means can be searched):
# ALL          |FULLVER|REPOS|PKGPATH|PKGNAME|
# BIN          Pathname + name of file to execute Odoo (+)
# CONFN        Configuration filename (+)
# DB_USER      Postgres username in multi-version environment
# DDIR         Data directory
# DIRLEVEL     Directoy level: may be OCB,repository,module,other
# FLOG         Log full filename (+)
# FPID         PID full filename (+)
# FULLVER      Odoo version, format like 11.0
# FULL_SVCNAME Pathname + filename to start/stop Odoo service (+)
# GIT_BRANCH   Git branch
# GIT_OPTS     Git switches to clone Odoo project
# GIT_ORG      URL of git organization of specific Odoo version
# GIT_ORGID    Identification of git organization
# GIT_ORGNM    Name of git organization of specific Odoo version
# GIT_PROT     Git protocol (git or https)
# GIT_URL      URL to download git project (ends with .git)
# HOME         Specific Odoo repository directory (i.e /opt/odoo/11.0/l10n-italy)
# INVALID_MODNAMES
# INVALID_MODNAMES_RE
# LICENSE      License (AGPL or LGPL or OPL)
# LCONFN       Local Configuration filename (+)
# LPPORT       Long polling port
# MAJVER       Major Odoo version
# MANIFEST     Manifest filename (__openerp__.py or __manifest__.py)
# OCB_SUBDIRS
# OCB_SUBDIRS_RE
# OPTS_ASM     Undocumented (deprecated)
# PARENTDIR    Parent directory of specific Odoo module (i.e. /opt/odoo/11.0/l10n-italy)
# PKGNAME      Package (module) name
# PKGPATH      Home directory of Odoo module (i.e. /opt/odoo/11.0/l10n-italy/l10n_it)
# REPOS        Repository name
# ROOT         Odoo home directory of specific vid/version (i.e. /opt/odoo/11.0)
# RORIGIN      Remote git origin of Odoo repository (actual value|default)
# RPCPORT      Xmlrpc port in multi-version environment
# RUPSTREAM    Remote git upstream of Odoo repository (actual value|default)
# SVCNAME      Service name to start/stop Odoo service
# URL          URL to source git project (default value, deprecated: use GIT_URL)
# URL_BRANCH   URL tp specific version of source git project (default value)
# USER         Deprecated: use DB_USER
# VCS          If GIT repository return "git" otherwise return ""
# VDIR         Virtual directory
# VENV         Return 1 if path is in virtualenv
#
# -------------------------------
# Environment variables
# ODOO_DB_USER"     -> db username (def odoo%(MAJVER)s)
# ODOO_GIT_ORGID    -> default git organization
# ODOO_GIT_HOSTNAME -> git hostname (def github.com)
# ODOO_GIT_PROT     -> default protcocl (git|https) for default git organization
# ODOO_GIT_SHORT    -> regex of git organizzations with short name (def /(oca)/)
# ODOO_GIT_MULTI    -> multi version environment
#

#__version__=2.0.1


ODOO_FVERS="16\.0|15\.0|14\.0|13\.0|12\.0|11\.0|10\.0|9\.0|8\.0|7\.0|6\.1"
ODOO_VERS="16|15|14|13|12|11|10|9|8|7|6"
DEFMLIST="OCB account-analytic account-budgeting account-closing
 account-consolidation account-financial-reporting account-financial-tools
 account-fiscal-rule account-invoice-reporting account-invoicing
 account-payment account-reconcile ansible-odoo apps-store bank-payment
 bank-statement-import brand business-requirement calendar commission
 community-data-files connector contract contribute-md-template
 credit-control crm currency data-protection ddmrp delivery-carrier department
 dms donation e-commerce edi event field-service fleet geospatial helpdesk
 hr hr-attendance hr-expense hr-holidays infrastructure intrastat-extrastat
 iot knowledge l10n-italy maintenance management-system
 manufacture manufacture-reporting margin-analysis
 mis-builder mis-builder-contrib multi-company operating-unit partner-contact
 payroll pms pos product-attribute product-configurator product-kitting
 product-pack product-variant program project project-agile project-reporting
 purchase-reporting purchase-workflow queue report-print-send reporting-engine
 rma role-policy sale-financial sale-reporting sale-workflow search-engine
 server-auth server-backend server-brand server-env server-tools server-ux
 social stock-logistics-barcode stock-logistics-reporting
 stock-logistics-tracking stock-logistics-transport stock-logistics-warehouse
 stock-logistics-workflow storage survey timesheet web webhook
 webkit-tools website website-cms website-themes wms zerobug-test"
OCB_SUBDIRS="addons build debian dist doc docs egg-info _extensions filestore history howtos images odoo openerp redhat reference scripts server _static win32"
OCB_SUBDIRS_RE="^(${OCB_SUBDIRS// /|})$"
INVALID_MODNAMES="$OCB_SUBDIRS conf cover .cover .coverage egg-info .git html .idea latex node_modules openupgrade setup _static tests themes travis _travis __to_remove __unported__"
INVALID_MODNAMES_RE="^(${INVALID_MODNAMES// /|})$"
REPS_EXTRA="^(didotech_80|grymb|maintainer-quality-tools|maintainer-tools|tools|uncovered|VME|OpenUpgrade|Odoo-samples|dotnet|interface-github|odoorpc|openupgradelib|pylint-odoo|rest-framework|runbot-addons)$"
PRIVATE_REPS="(accounting|uncovered)"
REPT_ORG_MATRIX="acespritech/openerp_gantt_chart_modification,odoomrp/odoomrp-wip,"\
"local/didotech_80,zeroincombenze/profiles,local/uncovered,local/mymodules,local/themes,local/woven_fabric,"\
"local/zeroincombenze,local/cscs_addons,local/account_banking_cscs,"\
"zeroincombenze/l10n-italy-supplemental,"\
"OCA/pylint-odoo,OCA/operating-unit,"\
"OCA/runbot-addons,OCA/interface-github,OCA/OpenUpgrade,"\
"OCA/maintainer-quality-tools,OCA/odoo-sentinel,OCA/openupgradelib,"\
"OCA/maintainer-tools,OCA/server-env,"\
"OCA/ansible-odoo,OCA/connector-ecommerce,"\
"OCA/odoorpc,OCA/oca-customOCA/oca-decorators,"\
"OCA/odoo-sphinx-autodoc,OCA/infrastructure-dns,OCA/dotnet,"\
"OCA/connector-magento-php-extension,zeroincombenze/zerobug-test,"\
"LibrERP-network/accounting,LibrERP/connector-prestashop,"\
"LibrERP/double-trouble,LibrERP/custom-addons,LibrERP/aeroolib,LibrERP/generic,"\
"local/addons_kalamitica,local/nardo_modules"


get_odoo_major_ver() {
    local v="" x
    for x in $(echo "$1" | grep --color=never -Eo '[0-9]+'); do
      [[ $x =~ ($ODOO_VERS) ]] && v=$x && break
    done
    [[ -z $v && $1 =~ librerp6 ]] && v="6"
    [[ -z $v ]] && v="12"
    echo $v
}

get_odoo_full_ver() {
    local v="" x
    for x in $(echo "$1" | grep --color=never -Eo '[0-9]+\.[0-9]+'); do
      [[ $x =~ ($ODOO_FVERS) && ${x/./} -gt ${v/./} ]] && v=$x && break
    done
    if [[ -z $v ]]; then
      for x in $(echo "$1" | grep --color=never -Eo '[0-9]+'); do
        [[ $x =~ ($ODOO_VERS) ]] && v=$x && break
      done
      [[ -n $v && $v != "6" ]] && v="${v}.0"
      [[ $v == "6" ]] && v="6.1"
    fi
    [[ -z $v && $1 =~ librerp6 ]] && v="6.1"
    [[ -z $v ]] && v="12.0"
    echo $v
}

find_odoo_ver() {
    #find_odoo_ver(odoo_root_dir)
    local ldir odoo_fver x ODOO_ROOT
    if [[ -z $HOME_DEVEL ]]; then
        [[ -d $HOME/odoo ]] && ODOO_ROOT="$HOME/odoo" || ODOO_ROOT="$HOME"
    else
        ODOO_ROOT=$(readlink -f $HOME_DEVEL/..)
    fi
    [[ -n "$1" ]] && pushd $1 &>/dev/null
    while [[ -z "$odoo_fver" ]]; do
        for ldir in $PWD/odoo $PWD/openerp $PWD/server/openerp; do
            if [[ -d $ldir && -f $ldir/release.py ]]; then
                pushd $ldir &>/dev/null
                x=$(echo -e "from __future__ import print_function\nimport release\nprint(release.version)\n" | python)
                odoo_fver=$(get_odoo_full_ver "$x")
                popd &>/dev/null
                break
            fi
        done
        [[ $PWD == $ODOO_ROOT ]] && break
        [[ ! $PWD == "/" ]] && PWD=$($READLINK -f "$PWD/..") || break
    done
    [[ -n "$1" ]] && popd &>/dev/null
    echo "$odoo_fver"
}

is_ocb_dir() {
    local x
    [[ -z $1 ]] && return 1
    for x in $1/odoo-bin $1/odoo/odoo-bin $1/openerp-server $1/odoo/openerp-server $1/server/openerp-server; do
        [[ -x $x ]] && return 0
    done
    return 1
}

is_repos() {
    local x
    [[ -z $1 ]] && return 1
    [[ (-f $1/.travis.yml || -f $1/.gitlab-ci.yml) && (-d $1/.git || -f $1/requirements.txt || -f $1/oca_dependencies.txt || -f $1/README.rst || -f $1/README.md) ]] && return 0
    return 1
}

is_module() {
    local x
    [[ -z $1 ]] && return 1
    [[ (-f $1/__manifest__.py || -f $1/__openerp__.py) && -f $1/__init__.py ]] && return 0
    return 1
}

traverse() {
    local d p=0 r
    local PKGNAME=$2 PKGPATH=$3 PARENTDIR=$4 REPOS=$5 PRJPATH=$6
    if [[ -n $1 ]]; then
        for d in $(find $1 -maxdepth 2); do
            [[ -d "$d" ]] && $(is_module "$d") && PKGPATH=$d && PKGNAME=$(basename $d) && PARENTDIR=$($READLINK -e $d/..) && p=1 && break
        done
        if [ $p -ne 0 ]; then
            r="$(basename $1)"
            [[ ! $r =~ $rex && ! $r =~ $INVALID_MODNAMES_RE ]] && REPOS=$r && PRJPATH=$1
        fi
    fi
    echo "$PKGNAME|$PKGPATH|$PARENTDIR|$REPOS|$PRJPATH"
}

build_odoo_param() {
    # build_odoo_param(ALL|BIN|CONFN|DB_USER|DDIR|DIRLEVEL|FLOG|FPID|FULLVER|FULL_SVCNAME|GIT_BRANCH|GIT_OPTS|GIT_ORG|GIT_ORGNM|GIT_PROT|GIT_URL|HOME|INVALID_MODNAMES|INVALID_MODNAMES_RE|LICENSE|LCONFN|LPPORT|MAJVER|MANIFEST|OCB_SUBDIRS|OCB_SUBDIRS_RE|OPTS_ASM|PARENTDIR|PKGNAME|PKGPATH|REPOS|ROOT|RORIGIN|RPCPORT|RUPSTREAM|SVCNAME|UPSTREAM|URL|URL_BRANCH|USER|VCS|VDIR|VENV
    #                  vid [(search|DEBUG|default|tree|SERVER|<rptname>|<modname>)] [oca|zero|zero-http|zero-git|librerp|flectra] [(search|DEBUG|default|tree|SERVER)])
    [[ :$SHELLOPTS: =~ :xtrace: ]] && set +x && local SETX="set -x"
    if [[ $1 =~ (INVALID_MODNAMES|INVALID_MODNAMES_RE|OCB_SUBDIRS|OCB_SUBDIRS_RE) ]]; then
        echo "${!1}"
        $SETX
        return
    fi
    READLINK=$(which greadlink 2>/dev/null) || READLINK=$(which readlink 2>/dev/null)
    local ODOO_ROOT
    local VENV=0 main exorg spec
    local ITEM=$1 ROOT PARENTDIR PRJPATH
    local DIRLEVEL FULLVER LICENSE MAJVER odoo_vid noenv_vid MULTIVER REPOS
    local GIT_URL GIT_ORG GIT_ORGID GIT_ORGNM GIT_PROT GIT_OPTS ORGSFX OPTS_ASM
    local RGIT_ORGID RGIT_ORGNM
    local RUPSTREAM RORIGIN DB_USER
    local PKGPATH PKGNAME ORGNM VDIR
    local cdir d ldir p p1 p11 p2 p3 p4 pd r x
    if [[ -z $HOME_DEVEL ]]; then
        [[ -d $HOME/odoo ]] && ODOO_ROOT="$HOME/odoo" || ODOO_ROOT="$HOME"
    else
        ODOO_ROOT=$(readlink -f $HOME_DEVEL/..)
    fi
    p1="v|V|ODOO|ocb|OCB"
    p2="odoo|oca|powerp|librerp|librerp6|zero|zeroincombenze"
    local rex="^(VENV[_-]([0-9]{3,10})?)?($p1|$p2)?[_-]?($ODOO_FVERS|$ODOO_VERS)[_-]?($p2)?"
    local reo="^($p1)"
    local reg="($p2)"
    local ref="($ODOO_FVERS)"
    [[ -n "$ODOO_GIT_SHORT" ]] && SHORT="$ODOO_GIT_SHORT" || SHORT="(oca)"
    [[ -z "$ODOO_GIT_HOSTNAME" ]] && ODOO_GIT_HOSTNAME="(github.com)"
    [[ -z "$ODOO_DB_USER" ]] && ODOO_DB_USER="odoo%(MAJVER)s"
    [[ $3 =~ ^((DEBUG|default|search|SERVER|tree|odoo|short),?)+$ ]] && spec=$3 || REPOS=$3
    [[ $5 =~ ^((DEBUG|default|search|SERVER|tree|odoo|short),?)+$ ]] && spec=$5
    exorg=0
    GIT_ORGNM=""
    GIT_PROT=""
    RUPSTREAM=""
    RORIGIN=""
    if [[ "$2" =~ (^\.$|^\.\.$|(\./|\.\./|~/|/)) ]]; then
        if [[ $ITEM == "DIRLEVEL" ]]; then
          $(is_module "$2") && DIRLEVEL="module"
          [[ -z "$DIRLEVEL" ]] && $(is_ocb_dir "$2") && DIRLEVEL="OCB"
          [[ -z "$DIRLEVEL" ]] && $(is_repos "$2") && DIRLEVEL="repository"
          [[ -z "$DIRLEVEL" ]] && DIRLEVEL="other"
          echo $DIRLEVEL
          $SETX
          return
        fi
        [[ -n "$2" ]] && cdir=$($READLINK -f $2) || cdir=$($READLINK -f $PWD)
        [[ -f $cdir ]] && cdir=$(dirname $cdir)
        while [[ (-z "$odoo_vid" || -z "$ROOT") && -n "$cdir" ]]; do
            if $(is_module "$cdir"); then
                PKGPATH=$cdir
                PKGNAME=$(basename $cdir)
                PARENTDIR=$(dirname $cdir)
                if [[ -z ""$LICENSE"" ]]; then
                  [[ -f $cdir/__openerp__.py ]] && LICENSE=$(grep ["']license['"]: $cdir/__openerp__.py|awk -F: '{print $2}'|tr -d "',\" \n")
                  [[ -f $cdir/__manifest__.py ]] && LICENSE=$(grep ["']license['"]: $cdir/__manifest__.py|awk -F: '{print $2}'|tr -d "',\" \n")
                fi
            elif $(is_ocb_dir "$cdir"); then
                [[ -z "$REPOS" ]] && REPOS=OCB
                [[ -z "$ROOT" ]] && ROOT=$cdir
                [[ -z "$PKGPATH" ]] && PKGPATH=$cdir
                [[ -z "$PRJPATH" ]] && PRJPATH=$cdir
                [[ -z "$PARENTDIR" ]] && PARENTDIR=$($READLINK -e $cdir/..)
                odoo_vid=$(basename $cdir)
                [[ $VENV -eq 0 && -f $cdir/venv_odoo/bin/activate ]] && VENV=1 && VDIR=$($READLINK -e $cdir/venv_odoo)
                [[ $VENV -eq 0 && -f $cdir/../venv_odoo/bin/activate ]] && VENV=1 && VDIR=$($READLINK -e $cdir/../venv_odoo)
                [[ $VENV -eq 0 && -f $cdir/../VENV-${odoo_vid}/bin/activate ]] && VENV=1 && VDIR=$($READLINK -e $cdir/../VENV-${odoo_vid})
                [[ $odoo  == "odoo" ]] && cdir=$($READLINK -e $cdir/..) && odoo_vid=$(basename $cdir)
                FULLVER=$(find_odoo_ver $cdir)
                [[ -f $cdir/venv_odoo/bin/activate ]] && VENV=1 && VDIR=$cdir/venv_odoo
            elif $(is_repos "$cdir"); then
                r=$(basename $cdir)
                [[ ! $r =~ $rex ]] && REPOS=$r && PRJPATH=$cdir
                [[ -z "$PARENTDIR" ]] && PARENTDIR=$($READLINK -e $cdir/..)
                [[ -z "$PARENTDIR" ]] && PARENTDIR=$($READLINK -e $cdir/..)
                if [[ -z "$PKGNAME" ]]; then
                    IFS="|" read PKGNAME PKGPATH PARENTIDR REPOS PRJPATH <<< $(traverse "$cdir" "$PKGNAME" "$PKGPATH" "$PARENTIDR" "$REPOS" "$PRJPATH")
                fi
            elif [[ (-n "$PKGNAME" && -d $cdir/$PKGNAME) ]]; then
                r=$(basename $cdir)
                [[ ! $r =~ $rex ]] && REPOS=$r && PRJPATH=$cdir
                [[ -z "$PARENTDIR" ]] && PARENTDIR=$($READLINK -e $cdir/..)
                if [[ -z "$PKGNAME" ]]; then
                    IFS="|" read PKGNAME PKGPATH PARENTIDR REPOS PRJPATH <<< $(traverse "$cdir" "$PKGNAME" "$PKGPATH" "$PARENTIDR" "$REPOS" "$PRJPATH")
                fi
            elif [[ -z "$PKGNAME" ]]; then
                IFS="|" read PKGNAME PKGPATH PARENTIDR REPOS PRJPATH <<< $(traverse "$cdir" "$PKGNAME" "$PKGPATH" "$PARENTIDR" "$REPOS" "$PRJPATH")
            fi
            if [[ -z "$GIT_ORGNM" && -d $cdir/.git ]] && $(git status -s &>/dev/null); then
                x=$(git rev-parse --show-toplevel 2>/dev/null)
                if [[ -z $x || $x == $cdir ]]; then
                    GIT_URL=$(git remote get-url --push origin 2>/dev/null)
                    RUPSTREAM=$(git remote get-url --push upstream 2>/dev/null)
                    RORIGIN=$(git remote get-url --push origin 2>/dev/null)
                    if [[ -n "$GIT_URL" ]]; then
                        GIT_ORGNM=$(basename $(dirname $(git remote -v|echo $GIT_URL|awk -F: '{print $2}')))
                        GIT_PROT=$(echo $GIT_URL|awk -F: '{print $1}')
                        VCS="git"
                    fi
                    # GIT_BRANCH=$(git branch --show-current)
                    GIT_BRANCH=$(git branch --list|grep "^\* "|grep --color=never -Eo "[a-zA-Z0-9_-]+"|head -n1|tr -d "\n")
                fi
            fi
            [[ $cdir == $ODOO_ROOT ]] && break
            [[ ! $cdir == "/" ]] && cdir=$($READLINK -e $cdir/..) || cdir=
        done
    else
        IFS=/ read odoo_vid x <<<$2
        [[ -n $x ]] && REPOS=$x
        [[ $odoo_vid =~ ^VENV ]] && VENV=1 && VDIR="$ODOO_ROOT/$odoo_vid"
    fi
    if [[ $ITEM == "DIRLEVEL" ]]; then
        DIRLEVEL="other"
        echo $DIRLEVEL
        $SETX
        return
    fi
    [[ -z $REPOS ]] && REPOS=OCB
    x=$(echo $odoo_vid | grep --color=never -Eo "VENV[_-]([0-9]{3,10})?/?" | tail -n1)
    [[ -n $x ]] && x=$(echo $odoo_vid | grep --color=never -Eo "^.*$x")
    [[ -n $x ]] && noenv_vid=${odoo_vid/$x/} || noenv_vid=$odoo_vid
    [[ $noenv_vid =~ ^(v|V)($ODOO_VERS)[^0-9]* ]] && main=1 || main=0
    [[ -z "$FULLVER" && -n "$noenv_vid" && ($noenv_vid =~ $rex || $noenv_vid =~ librerp[6]?) ]] && FULLVER=$(get_odoo_full_ver "$noenv_vid")
    [[ -z "$FULLVER" && $ODOO_BRANCH =~ $ref ]] && FULLVER=$ODOO_BRANCH
    [[ -z "$FULLVER"  ]] && FULLVER=12.0
    [[ -z "$GIT_BRANCH" ]] && GIT_BRANCH="$FULLVER"
    MAJVER=$(get_odoo_major_ver "$FULLVER")
    if [[ "$ITEM" == "MANIFEST" ]]; then
        [[ $MAJVER -ge 10 ]] && echo "__manifest__.py" || echo "__openerp__.py"
        $SETX
        return
    fi
    [[ -n $ODOO_ODOO_GIT_MULTI ]] && MULITVER=$ODOO_GIT_MULTI || [[ ${opt_multi:-0} -ne 0 ]] && MULTIVER=1 || MULTIVER=0
    ORGSFX=$(echo $noenv_vid | grep --color=never -Eo "[-_][a-z][a-z0-9]+$" | grep --color=never -Eo "[a-z0-9]+")
    if [[ -n $ORGSFX ]]; then
        [[ $ORGSFX =~ -git$ ]] && GIT_PROT="git" && ORGSFX=${ORGSFX:0: -4}
        [[ $ORGSFX =~ -http$ ]] && GIT_PROT="https" && ORGSFX=${ORGSFX:0: -5}
        [[ $ORGSFX == "librerp6" ]] && ORGSFX="librerp"
    fi
    if [[ -n $ORGSFX && $ORGSFX =~ ^$reg ]]; then
        exorg=1
        GIT_ORGID=$(echo $ORGSFX | grep --color=never -Eo "^$reg" | head -n1)
        [[ $GIT_ORGID == "librerp" && $FULLVER == "6.1" ]] && GIT_ORGID="librerp6"
        ORGSFX=${ORGSFX/$GIT_ORGID/}
    fi
    if [[ -z "$GIT_ORGNM" ]]; then
        if [[ $REPOS =~ $INVALID_MODNAMES_RE ]]; then
            GIT_ORGID=""
            GIT_PROT=""
            RUPSTREAM=""
        else
            [[ -n "$4" ]] && GIT_ORGID=$4 && exorg=1
            [[ -z $GIT_ORGID && $noenv_vid =~ ^(OCB|ocb) ]] && GIT_ORGID="oca" && exorg=1
            [[ -z $GIT_ORGID && $noenv_vid =~ ^(ODOO|odoo) ]] && GIT_ORGID="odoo" && exorg=0    ## TODO
            [[ -z $GIT_ORGID && $noenv_vid =~ ^$reg ]] && GIT_ORGID=$(echo $noenv_vid | grep --color=never -Eo $reg | head -n1) && [[ ! $noenv_vid =~ ^odoo ]] && exorg=1
            [[ -z $GIT_ORGID && ! $noenv_vid =~ ^$reg && -n "$ODOO_GIT_ORGID" ]] && GIT_ORGID=$(echo $ODOO_GIT_ORGID|cut -d"|" -f1|tr -d "("|tr -d ")") && GIT_PROT="git"
            [[ -z "$GIT_ORGID" ]] && GIT_ORGID="odoo"
        fi
        GIT_ORGNM="$GIT_ORGID"
        [[ $GIT_ORGID == "oca" ]] && GIT_ORGNM="OCA"
        [[ $GIT_ORGID =~ ^(zero|zeroincombenze)$ ]] && GIT_ORGID="zero" && GIT_ORGNM="zeroincombenze" && RUPSTREAM="https://github.com/OCA/$REPOS.git"
        [[ $GIT_ORGID == "powerp" ]] && GIT_ORGNM="PowERP-cloud" && RUPSTREAM="https://github.com/OCA/$REPOS.git" && GIT_BRANCH="master"
        [[ $GIT_ORGID == "librerp" ]] && GIT_ORGNM="LibrERP-network" && RUPSTREAM="https://github.com/OCA/$REPOS.git"
        [[ $GIT_ORGID =~ ^librerp[6]?$ && $FULLVER == "6.1" ]] && GIT_ORGNM="iw3hxn" && GIT_BRANCH="master"
        # [[ $GIT_ORGID == "librerp" && "$FULLVER" == "12.0" ]] && GIT_ORGID="librerp" && GIT_ORGNM="librerp" && RUPSTREAM="https://github.com/OCA/$REPOS.git"
        if [[ "$REPT_ORG_MATRIX," =~ "/$REPOS," ]]; then
            r=$(echo "$REPT_ORG_MATRIX," | grep --color=never -Eo "[A-Za-z0-9_.-]+/$REPOS,")
            IFS=/ read GIT_ORGNM x <<<$r
        elif [[ ( $GIT_ORGID =~ ^(librerp)$ || $GIT_ORGNM =~ (LibrERP-network|LibrERP) ) && ( ! $REPOS =~ (l10n-italy|server) || ! $FULLVER =~ (12.0|14.0) ) ]]; then
            RGIT_ORGID="zero"
            RGIT_ORGNM="zeroincombenze"
        fi
    elif [[ ( $GIT_ORGID =~ ^(librerp)$ || $GIT_ORGNM =~ (LibrERP-network|LibrERP) ) && ( ! $REPOS =~ (l10n-italy|server) || ! $FULLVER =~ (12.0|14.0) ) ]]; then
        RGIT_ORGID="zero"
        RGIT_ORGNM="zeroincombenze"
    fi
    [[ $GIT_ORGNM == "OCA" ]] && GIT_ORGID="oca"
    [[ $GIT_ORGNM == "zeroincombenze" ]] && GIT_ORGID="zero"
    [[ $GIT_ORGNM =~ ^(LibrERP-network|LibrERP) ]] && GIT_ORGID="librerp"
    [[ $GIT_ORGNM == "iw3hxn" ]] && GIT_ORGID="librerp6"
    [[ $GIT_ORGNM =~ ^(PowERP-cloud|powerp1) ]] && GIT_ORGID="powerp"
    [[ -z $GIT_ORGID ]] && GIT_ORGID="$GIT_ORGNM"
    [[ -n $ODOO_GIT_ORGID && ( $GIT_ORGID == $ODOO_GIT_ORGID || $GIT_ORGID =~ ^$ODOO_GIT_ORGID$ ) ]] && GIT_PROT="git"
    [[ -n $ODOO_GIT_PROT ]] && GIT_PROT="$ODOO_GIT_PROT"
    if [[ "$ITEM" == "LICENSE" ]]; then
        if [[ -z "$LICENSE" ]]; then
          [[ $GIT_ORGID == "powerp" ]] && LICENSE="OPL"
          [[ -z "$LICENSE" && $MAJVER -le 8 ]] && LICENSE="AGPL"
          [[ -z "$LICENSE" ]] && LICENSE="LGPL"
        else
          LICENSE=$(echo $LICENSE|grep --color=never -Eo [A-Z]+|head -n1)
        fi
        echo $LICENSE
        $SETX
        return
    fi
    if [[ -z $ROOT ]]; then
        if [[ $MULTIVER -eq 0 || $exorg -eq 0 || $main -ne 0 || ( -z $GIT_ORGID && $odoo_vid =~ $ref ) || ( -n $ODOO_GIT_ORGID && ( $GIT_ORGID == $ODOO_GIT_ORGID || $GIT_ORGID =~ ^$ODOO_GIT_ORGID$ ) && $odoo_vid =~ $ref ) || $odoo_vid =~ $reo ]]; then
            [[ $VENV -ne 0 ]] && ROOT=$ODOO_ROOT/$odoo_vid/odoo || ROOT=$ODOO_ROOT/$odoo_vid
        elif [[ $GIT_ORGID == "librerp6" ]]; then
            [[ $VENV -ne 0 ]] && ROOT=$ODOO_ROOT/${GIT_ORGID}/odoo || ROOT=$ODOO_ROOT/${GIT_ORGID}
        elif [[ $GIT_ORGID =~ ^$SHORT ]]; then
            [[ $VENV -ne 0 ]] && ROOT=$ODOO_ROOT/${GIT_ORGID}${MAJVER}/odoo || ROOT=$ODOO_ROOT/${GIT_ORGID}${MAJVER}
        else
            [[ $VENV -ne 0 ]] && ROOT=$ODOO_ROOT/odoo$MAJVER-$GIT_ORGID/odoo || ROOT=$ODOO_ROOT/odoo$MAJVER-$GIT_ORGID
        fi
    fi
    if [[ -z $PKGPATH ]]; then
        if [[ $REPOS == "OCB" ]]; then
            PKGPATH=$ROOT
            PARENTDIR=$(dirname $ROOT)
        else
            PKGPATH="$ROOT/$REPOS"
            PARENTDIR=$(dirname $PKGPATH)
        fi
    fi
    if [[ -z $PRJPATH ]]; then
        [[ $REPOS == "OCB" ]] && PRJPATH=$ROOT || PRJPATH="$ROOT/$REPOS"
    fi
    [[ -z $RUPSTREAM && $GIT_ORGID =~ ^(zero|powerp|librerp[6]?)$ ]] && RUPSTREAM="https://github.com/OCA/$REPOS.git"
    [[ -z "$GIT_PROT" ]] && GIT_PROT="https"
    [[ "$FULLVER" == "6.1" ]] && RUPSTREAM=""
    if [[ $REPOS =~ $REPS_EXTRA ]]; then
        GIT_ORGID=""
        GIT_ORGNM=""
        GIT_PROT=""
        RUPSTREAM=""
    fi
    [[ $GIT_ORGID =~ ^librerp[6]?$ && $MAJVER == "6" && "$REPOS" == "OCB" ]] && REPOS="server"
    [[ $GIT_ORGID == "odoo" && ! "$REPOS" == "OCB" ]] && GIT_ORGID="oca" && GIT_ORGNM="OCA"
    [[ -z $RGIT_ORGID ]] && RGIT_ORGID=$GIT_ORGID
    [[ -z $RGIT_ORGNM ]] && RGIT_ORGNM=$GIT_ORGNM
    if [[ $REPOS =~ $PRIVATE_REPS ]]; then
        GIT_ORG="git@github.com:$RGIT_ORGNM"
        [[ "$GIT_PROT" == "git" ]] && GIT_OPTS="" || GIT_OPTS="--depth 1 --single-branch"
        OPTS_ASM=
    elif [[ -n "$GIT_PROT" ]]; then
        if [[ "$GIT_PROT" == "git" ]]; then
            GIT_ORG="git@github.com:$RGIT_ORGNM"
            GIT_OPTS=""
            OPTS_ASM=
        else
            GIT_ORG="https://github.com/$RGIT_ORGNM"
            GIT_OPTS="--depth 1 --single-branch"
            OPTS_ASM="-1"
        fi
    else
        GIT_ORG=""
        GIT_OPTS=""
        OPTS_ASM=
    fi
    [[ -n "$GIT_ORG" && -n "$REPOS" ]] && URL=$GIT_ORG/$REPOS
    [[ -n "$GIT_ORG" && "$REPOS" == "OCB" && $GIT_ORGID == "odoo" ]] && URL=$GIT_ORG/odoo
    [[ -n "$GIT_ORG" && "$REPOS" == "OCB" && $GIT_ORGID == "oca" && $spec =~ odoo ]] && URL="https://github.com/odoo/odoo"
    [[ -n "$URL" ]] && URL_BRANCH="$URL/tree/$FULLVER"
    [[ -z "$GIT_URL" && -n "$URL" ]] && GIT_URL="${URL}.git"
    [[ -z "$RORIGN" ]] && RORIGIN=$GIT_URL
    [[ -z "$RUPSTREAM" ]] && RUPSTREAM=$GIT_URL
    if [[ $main -ne 0 ]]; then
        DB_USER="odoo"
    elif [[ $MAJVER -lt 8 && $USER == "openerp" ]]; then
        DB_USER="openerp"
    elif [[ $MULTIVER -ne 0 ]]; then
        DB_USER=${ODOO_DB_USER/\%(MAJVER)s/$MAJVER}
        DB_USER=${DB_USER/\%(ORGSFX)s/$ORGSFX}
    else
        DB_USER="odoo"
    fi
    [[ -z "$VDIR" ]] && VDIR="$ODOO_ROOT/$FULLVER/venv_odoo"
    if [[ "$ITEM" =~ ^(DB_USER|FULLVER|GIT_BRANCH|GIT_OPTS|GIT_ORG|GIT_ORGID|GIT_ORGNM|GIT_URL|MAJVER|OPTS_ASM|PARENTDIR|PKGNAME|PKGPATH|REPOS|ROOT|RORIGIN|RUPSTREAM|URL|URL_BRANCH|VCS|VDIR|VENV)$ ]]; then
        echo "${!ITEM}"
        $SETX
        return
    fi
    if [[ $ITEM == "ALL" ]]; then
        echo "|$FULLVER|$REPOS|$PKGPATH|$PKGNAME|"
        $SETX
        return
    elif [[ $ITEM == "USER" ]]; then
        echo "$DB_USER"
        $SETX
        return
    elif [[ $ITEM == "HOME" ]]; then
        echo "$PRJPATH"
        $SETX
        return
    elif [[ $ITEM == "RPCPORT" ]]; then
        if [[ $spec =~ (debug|DEBUG) ]]; then
            ((p = 18060 + $MAJVER))
        elif [[ $main -ne 0 || $MULTIVER -eq 0 ]]; then
            p=8069
        elif [[ $MULTIVER -ne 0 ]]; then
            if [ $exorg -eq 0 ]; then
                ((p = 8160 + $MAJVER))
            elif [[ $GIT_ORGID == "oca" ]]; then
                ((p = 8260 + $MAJVER))
            elif [[ $GIT_ORGID =~ ^(powerp|librerp[6]?)$ ]]; then
                ((p = 8360 + $MAJVER))
            elif [[ $GIT_ORGID =~ ^(zero|flectra)$ ]]; then
                ((p = 8460 + $MAJVER))
            else
                ((p = 8160 + $MAJVER))
            fi
        else
            p=8069
        fi
        echo $p
        $SETX
        return
    elif [[ $ITEM == "LPPORT" ]]; then
        if [[ $spec =~ (debug|DEBUG) ]]; then
            ((p = 18160 + $MAJVER))
        elif [[ $main -ne 0 || $MULTIVER -eq 0 ]]; then
            p=8072
        elif [[ $MULTIVER -ne 0 ]]; then
            if [[ $exorg -eq 0 ]]; then
                ((p = 8130 + $MAJVER))
            elif [[ $GIT_ORGID == "oca" ]]; then
                ((p = 8230 + $MAJVER))
            elif [[ $GIT_ORGID =~ ^(powerp|librerp[6]?)$ ]]; then
                ((p = 8330 + $MAJVER))
            elif [[ $GIT_ORGID =~ ^(zero|flectra)$ ]]; then
                ((p = 8430 + $MAJVER))
            else
                ((p = 8130 + $MAJVER))
            fi
        else
            p=8072
        fi
        echo $p
        $SETX
        return
    elif [[ $ITEM == "LCONFN" ]]; then
        [[ $MAJVER -ge 10 ]] && echo ".odoorc" || echo ".openerp_serverrc"
        $SETX
        return
    elif [[ $ITEM == "DDIR" ]]; then
        [[ $VENV -ne 0 ]] && p="$(dirname $ROOT)/$odoo_vid/.local/share" || p="$(dirname $ROOT)/.local/share"
        if [[ $MAJVER -lt 8 ]]; then
            p="$ROOT/openerp/filestore"
        elif [[ $odoo_vid =~ ^($ODOO_ROOT/)?VENV ]]; then
            p="$ODOO_ROOT/VENV-$FULLVER/.local/share/Odoo"
        elif [[ $noenv_vid =~ ^(v|V) ]]; then
            p="$p/Odoo"
        elif [[ $MULTIVER -ne 0 && $VENV -eq 0 ]]; then
            p="$p/Odoo$MAJVER"
        else
            p="$p/Odoo"
        fi
        if [[ $spec =~ search ]]; then
            pd=$p
            p1=/etc/odoo/
            p11=/etc/
            p4=.conf
        else
            echo $p
            $SETX
            return
        fi
    elif [[ $ITEM == "CONFN" ]]; then
        p1=/etc/odoo/
        p11=/etc/
        p4=.conf
    elif [[ $ITEM == "FULL_SVCNAME" || "$ITEM" == "SVCNAME" ]]; then
        p1=/etc/init.d/
        p11=
        p4=
    elif [[ $ITEM == "FLOG" ]]; then
        p1=/var/log/odoo/
        p11=/var/log/
        p4=.log
    elif [[ $ITEM == "FPID" ]]; then
        p1=/var/run/odoo/
        p11=/var/run/
        p4=.pid
    elif [[ $ITEM == "BIN" ]]; then
        if [[ $MAJVER -le 7 ]]; then
            p1=$PKGPATH/
            p11=$PKGPATH/server/
        else
            p1=$PKGPATH/
            p11=$PKGPATH/odoo/
        fi
        p4=
    else
        echo "Invalid parameter <$ITEM>!"
        exit 1
    fi
    if [[ $MULTIVER -ne 0 && $ITEM != "BIN" ]]; then
        if [[ $main -ne 0 ]]; then
            [[ $MAJVER -ge 8 ]] && p2=odoo || p2=openerp
        elif [[ $ITEM == "DDIR" && $VENV -ne 0 ]]; then
            p2=odoo
        elif [[ ! $ITEM =~ (CONFN|FULL_SVCNAME|SVCNAME|FLOG|FPID|DDIR) && $GIT_ORGID =~ ^$SHORT ]]; then
            p2="${GIT_ORGID}${MAJVER}"
        else
            p2="odoo${MAJVER}"
        fi
    elif [[ $ITEM == "BIN" ]]; then
        [[ $MAJVER -ge 10 ]] && p2=odoo || p2=openerp
    elif [[ $MAJVER -lt 7 || $odoo_vid =~ (v7|V7) ]]; then
        p2=openerp
    else
        p2="odoo"
    fi
    if [[ $ITEM =~ (CONFN|FULL_SVCNAME|SVCNAME|FLOG|FPID|DDIR) ]]; then
        p3=
        if [[ $MULTIVER -ne 0 ]]; then
            if [[ $exorg -ne 0 ]]; then
                [[ -z $ORGSFX ]] && p3="-${GIT_ORGID}"
                [[ -n $ORGSFX ]] && p3="-${GIT_ORGID}${ORGSFX}"
            elif [[ -n $ORGSFX ]]; then
                p3="-${ORGSFX}"
            elif [[ $GIT_ORGID != "odoo" && ( -z $ODOO_GIT_ORGID || ( $GIT_ORGID != $ODOO_GIT_ORGID && ! $GIT_ORGID =~ ^$ODOO_GIT_ORGID$ )) ]]; then
                p3="-${GIT_ORGID}"
            fi
        fi
        [[ ( -z $p3 || $p3 == "-odoo" ) && $MAJVER -lt 10 ]] && p3="-server"
        [[ $p3 == "-librerp6" ]] && p3="-librerp"
    elif [[ $MAJVER -ge 10 ]]; then
        [[ $ITEM == "BIN" ]] && p3=-bin || p3=
    else
        p3="-server"
    fi
    [[ $ITEM == "BIN" && ($spec =~ (SERVER|tree) || $MAJVER == 6 || $noenv_vid =~ ^(v7|V7)) ]] && p="$p11$p2$p3$p4" || p="$p1$p2$p3$p4"
    if [[ $spec =~ search ]]; then
        p=$(findpkg "$p2$p3$p4" "$p1 $p11")
        if [[ -z "$p" ]]; then
            p=$(findpkg "odoo$p3$p4" "$p1 $p11")
        fi
        if [[ -z "$p" && $MAJVER -lt 7 ]]; then
            p=$(findpkg "openerp$p4" "$p1 $p11")
            if [ -z "$p" ]; then
                p=$(findpkg "odoo$p3$p4" "$p1 $p11")
            fi
        elif [ -z "$p" -a $MAJVER -ge 7 ]; then
            p=$(findpkg "odoo$p4" "$p1 $p11")
            if [[ -z "$p" ]]; then
                p=$(findpkg "openerp$p3$p4" "$p1 $p11")
            fi
        fi
    fi
    if [[ $ITEM == "DDIR" ]]; then
        p=$(grep "data_dir *=" $p | awk -F= '{print $2}' | tr -d " ")
        [[ -z "$p" ]] && p=$pd
    elif [[ $ITEM == "SVCNAME" ]]; then
        p=$(basename $p)
    fi
    echo "$p"
    $SETX
}

discover_multi() {
    local v c=${opt_multi:-0}
    local ov=${ODOO_FVERS//|/ }
    opt_multi=${opt_multi:-0}
    [ $opt_multi -gt 0 ] && return
    local c=0
    for v in ${ov//\\/}; do
        odoo_bin=$(build_odoo_param BIN $v search)
        [[ -n "$odoo_bin" ]] && ((c++))
        [[ $c -gt 1 ]] && break
        odoo_bin=$(build_odoo_param BIN "V$v" search)
        [[ -n "$odoo_bin" ]] && ((c++))
        [[ $c -gt 1 ]] && break
        odoo_bin=$(build_odoo_param BIN $v search oca)
        [[ -n "$odoo_bin" ]] && ((c++))
        [[ $c -gt 1 ]] && break
    done
    [[ $c -gt 1 ]] && opt_multi=1
}

module_list() {
# module_list(odoo_fver excl_list git_org)
    # excl_list format: (aaa|b.*|...)
    local res=
    local fn ls
    local odoo_fver=$(build_odoo_param FULLVER "$1")
    local excl_list="$2$INVALID_MODNAMES_RE$REPS_EXTRA"
    excl_list="${excl_list//)\$^(/|}"
    excl_list="${excl_list//)\$(/|}"
    excl_list="${excl_list//)^(/|}"
    excl_list="${excl_list//)(/|}"
    local GIT_ORGNM=$(build_odoo_param GIT_ORGNM $1 "" $3)
    local WGET=$(which wget_odoo_repositories.py 2>/dev/null)
    ls=$($WGET -b $odoo_fver -G $GIT_ORGNM|awk -F"\t" '{print $2}')
    [[ -z $ls ]] && ls="$DEFMLIST"
    res=""
    for fn in $ls; do
      [[ -z "$excl_list" || ! $fn =~ $excl_list ]] && res="$res $fn"
    done
    echo $res
}


if [ "${BASH_SOURCE-}" == "$0" ]; then
    build_odoo_param "$@"
fi
