#!/usr/bin/env bash
#set -x

CURDIR=$(cd "$(dirname "$0")" && pwd)
BINDIR=$CURDIR
MANAGER_DIR=${MANAGER_DIR:-$(pwd)}
HOSTID=
INST_ID=
CONF_PACKAGE="$1"
TMPDIR=$(mktemp -d)

CONF_ROOT=$BINDIR/../etc
if [[ ! -d $CONF_ROOT/conf.d ]]; then
    CONF_ROOT=/etc/waarp
fi

MANAGER_CONF=${MANAGER_CONF:-${MANAGER_DIR}/etc/waarp-manager.ini}
if [[ ! -f $MANAGER_CONF ]]; then
    MANAGER_CONF=/etc/waarp-manager/waarp-manager.ini
fi


if [ -f "$CONF_ROOT/conf.d/$1/manager-send.conf" ]; then 
    .  "$CONF_ROOT/conf.d/$1/manager-send.conf"
fi

cleanup() {
    rm -rf "$TMPDIR"
}

trap cleanup EXIT

##
## FUNCTIONS 
##

set-hostid() {
  local file

  file=$(basename "${CONF_PACKAGE}")
  HOSTID=${file%-*}
  INST_ID=$(pgquery "SELECT id from partners where name='$HOSTID'" -tA)
}

set-manager-db-addr() {
    local DB_HOST=$(awk -F "=" '/Host/ {print $2}' "$MANAGER_CONF" | sed 's/ //g')
    local DB_PORT=$(awk -F "=" '/Port/ {print $2}' "$MANAGER_CONF" | sed 's/ //g' | tail -n 1)
    local DB_USER=$(awk -F "=" '/User/ {print $2}' "$MANAGER_CONF" | sed 's/ //g')
    local DB_PASS=$(awk -F "=" '/Password/ {print $2}' "$MANAGER_CONF" | sed 's/ //g')
    local DB_NAME=$(awk -F "=" '/^\s*Name/ {print $2}' "$MANAGER_CONF" | sed 's/ //g')

    MANAGER_DB="postgresql://$DB_USER:$DB_PASS@$DB_HOST:$DB_PORT/$DB_NAME"
}


pgquery() {
    psql "$MANAGER_DB" -c  "$@"
}

is-gateway_transfer() {
    local partnerType="$(pgquery "SELECT type FROM partners WHERE name='$HOSTID'" -tA)"
    [ "$partnerType" = "gw" ] || [ "$partnerType" = "transfer" ]
}

is-r66() {
    [ "$(pgquery "SELECT type FROM partners WHERE name='$HOSTID'" -tA)" = "r66" ]
}

is-gwsftp() {
    [ "$(pgquery "SELECT type FROM partners WHERE name='$HOSTID'" -tA)" = "gwsftp" ]
}

is-gwftp() {
    [ "$(pgquery "SELECT type FROM partners WHERE name='$HOSTID'" -tA)" = "gwftp" ]
}

add-passwd() {
    pgquery "SELECT interfaces.data->'clientLogin', interfaces.data->'clientPassword' FROM partners JOIN interfaces ON partners.ID=interfaces.partner_id WHERE sftp_gateway='$INST_ID' AND interfaces.protocol='sftp' AND interfaces.is_client=true" -t -A -F, | while read line; do
        local user=$(echo $line | cut -d, -f 1)
        local pass=$(echo $line | cut -d, -f 2)

        if [ "$pass" = "" ]; then
            pass=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
        fi

        local FTPASSWD=$BINDIR/../share/tools/ftpasswd
        if [[ ! -f $FTPASSWD ]]; then
            FTPASSWD=/usr/share/waarp/ftpasswd
        fi

        echo "$pass" | $FTPASSWD --passwd --file "$TMPDIR/sftp.passwd" \
            --name "$user" --uid 65534 --home /tmp \
            --shell /bin/false --stdin >/dev/null 2>&1
    done

    [ -f "$TMPDIR/sftp.passwd" ] || touch "$TMPDIR/sftp.passwd"
    add-to-package sftp.passwd
}

add-auth() {
    pgquery "SELECT interfaces.data->'clientLogin', interfaces.data->'serverPublicKey' FROM partners JOIN interfaces ON partners.ID=interfaces.partner_id WHERE gateway='$INST_ID' and interfaces.protocol='sftp'" -t -A -F, | while read line; do
        local user=$(echo "$line" | cut -d, -f 1)
        local key=$(echo "$line" | cut -d, -f 2)

        if [ ! "$key" = "" ]; then
            echo -e "$key" > "$TMPDIR/$user.authorized_keys"
            add-to-package "$user.authorized_keys"
        fi
    done
}

add-keys() {
    pgquery "SELECT interfaces.data->'clientPublicKey' FROM partners JOIN interfaces ON partners.ID=interfaces.partner_id WHERE partners.id='$INST_ID' AND interfaces.protocol='sftp'" -t -A -F, > "$TMPDIR/id_rsa.pub"
    add-to-package id_rsa.pub

    pgquery "SELECT interfaces.data->'clientPrivateKey' FROM partners JOIN interfaces ON partners.ID=interfaces.partner_id WHERE partners.id='$INST_ID' AND interfaces.protocol='sftp'" -t -A -F, > "$TMPDIR/id_rsa"
    add-to-package id_rsa
}

add-get-remote-file() {
local query="SELECT
                    flows.name,
                    rules.name,
                    origin_interfaces.protocol,
                    origin_interfaces.name,
                    origin_interfaces.address,
                    origin_interfaces.port,
                    origin_interfaces.data->>'authentMode',
                    (CASE WHEN origin.is_external
                    THEN
                      origin_interfaces.data->>'clientLogin'
                    ELSE
                      dest_interfaces.data->>'clientLogin'
                    END),
                    '',
                    '*'
             FROM rules
             JOIN flows ON flows.id=rules.flow_id
             JOIN (
               SELECT
                 origin.id AS origin_id,
                 dest.id AS dest_id,
                 MIN(origin_interfaces.priority) AS value
               FROM partners AS origin
               JOIN interfaces AS origin_interfaces ON origin.id = origin_interfaces.partner_id
               JOIN partners AS dest ON origin.id != dest.id
               JOIN interfaces AS dest_interfaces ON dest.id=dest_interfaces.partner_id AND origin_interfaces.protocol=dest_interfaces.protocol
               GROUP BY origin.id , dest.id
             ) AS priority ON priority.origin_id = rules.origin_id AND priority.dest_id = rules.destination_id
             JOIN interfaces AS origin_interfaces ON priority.origin_id=origin_interfaces.partner_id AND origin_interfaces.priority = priority.value
             JOIN interfaces AS dest_interfaces ON priority.dest_id=dest_interfaces.partner_id AND origin_interfaces.protocol=dest_interfaces.protocol
             JOIN partners AS dest ON dest.id = priority.dest_id
             JOIN partners AS origin ON origin.id = priority.origin_id
             WHERE rules.mode='receive'
               AND origin.is_server=true
               AND dest.id='$INST_ID'
             ORDER BY flows.name"

    local content="$(pgquery "$query" -t -F, -A)"
    if [ ! "$content" = "" ]; then
        echo -e "$content" > "$TMPDIR/get-file.list"
        add-to-package get-file.list
    fi
}

add-get-files() {
    local query="SELECT origin.name, flows.name, rules.name
                FROM rules
                    JOIN partners AS origin ON origin.id=rules.origin_id
                    JOIN flows ON flows.id=rules.flow_id
                    JOIN partners AS dest ON dest.id=rules.destination_id
                WHERE rules.mode='receive' AND dest.type='r66' AND dest.id='$INST_ID'
                ORDER BY origin.name"
   
    local content="$(pgquery "$query" -t -F, -A)"
    if [ ! "$content" = "" ]; then
        echo -e "$content" > "$TMPDIR/get-files.list"
        add-to-package get-files.list
    fi
}

add-get-sftp-files() {
    local query="SELECT flows.name,
                        rules.name,
                        origin_interfaces.address,
                        origin_interfaces.port,
                        origin_interfaces.data->'authentMode',
                        origin_interfaces.data->'clientLogin',
                        origin_interfaces.data->'clientPassword',
                        (CASE WHEN flows.params::json->>'SFTPREMOTEDIR'=''
                         THEN
                            '/'
                        ELSE
                            flows.params::json->>'SFTPREMOTEDIR'
                        END)
                    FROM rules
                        JOIN partners AS origin ON origin.id=rules.origin_id
                        JOIN interfaces AS origin_interfaces ON origin.id=origin_interfaces.partner_id
                        JOIN flows ON flows.id=rules.flow_id
                        JOIN partners AS dest ON dest.id=rules.destination_id
                    WHERE rules.mode='send'
                        AND origin.type='sftp'
                        AND origin_interfaces.protocol='sftp'
                        AND origin.is_server=true
                        AND dest.id='$INST_ID'
                    ORDER BY origin.name"
    
    local content="$(pgquery "$query" -t -F, -A)"
    if [ ! "$content" = "" ]; then
        echo -e "$content" > "$TMPDIR/get-files.list"
        add-to-package get-files.list
    fi
}

add-get-ftp-files() {
    local query="SELECT flows.name,
                     rules.name,
                     origin_interfaces.address,
                     origin_interfaces.port,
                     origin_interfaces.data->'clientLogin',
                     origin_interfaces.data->'clientPassword',
                     rules.origin_dir,
                     origin_interfaces.data->'secureMode',
                     origin_interfaces.data->'serverMode'
                FROM rules JOIN partners AS origin ON origin.id=rules.origin_id
                    JOIN interfaces AS origin_interfaces ON origin.id=origin_interfaces.partner_id
                    JOIN flows ON flows.id=rules.flow_id
                    JOIN partners AS dest ON dest.id=rules.destination_id
                WHERE rules.mode='receive' AND origin.type='ftp'
                   AND (origin_interfaces.protocol='ftp' OR origin_interfaces.protocol='ftps')
                   AND origin.is_server=true
                   AND dest.id='$INST_ID'
                ORDER BY origin.name"
    
    local content="$(pgquery "$query" -t -F, -A)"
    if [ ! "$content" = "" ]; then
        echo -e "$content" > "$TMPDIR/get-files.list"
        add-to-package get-files.list
    fi
}

add-user-dir() {
    local query="SELECT origin_interfaces.data->'clientLogin', flows.name
                FROM flows
                    JOIN rules ON flows.id=rules.flow_id
                    JOIN partners AS origin ON origin.id=rules.origin_id
                    JOIN interfaces AS origin_interfaces ON origin.id=origin_interfaces.partner_id
                    JOIN partners AS destination ON destination.id=rules.destination_id
                WHERE origin.type='sftp' AND destination.id='$INST_ID'"
    pgquery "$query" -t -A -F, | while read line; do
        local hostid=$(echo "$line" | cut -d, -f 1)
        local flow=$(echo "$line" | cut -d, -f 2)

        echo -e "$hostid"/"$flow" >> "$TMPDIR/user_dir.list"
    done
    if [ -f "$TMPDIR/user_dir.list" ]; then
        add-to-package user_dir.list
    fi
}

add-to-package() {
    cd "$TMPDIR"
    zip -q "$CONF_PACKAGE" "$1"
}

##
## MAIN 
##

set-manager-db-addr
set-hostid $@

is-gateway_transfer

if is-gateway_transfer; then
    add-get-remote-file
fi

is-r66

if is-r66; then
    add-get-files
fi

is-gwsftp

if is-gwsftp; then
    add-passwd
    add-auth
    add-keys
    add-user-dir
    add-get-sftp-files
fi

is-gwftp

if is-gwftp; then
    add-get-ftp-files
fi
