#!/bin/bash

REPO_TYPE=stable # Тип репозитория, необходимо заменить на stable, prerelease или testing, заменяется в job-е Jenkins-а
HOST=update.artix.su

URL="https://${HOST}/static/cs/install_scripts/${REPO_TYPE}/puppet_env"
URL_MAIN="https://${HOST}/static/cs/install_scripts/${REPO_TYPE}/main"
URL_CS="https://${HOST}/static/cs/install_scripts/${REPO_TYPE}/cs_env"

# импорт сертификата для docker
curl ${URL_MAIN}/import_docker_cert.sh -o /tmp/import_docker_cert.sh
. /tmp/import_docker_cert.sh

set -e

CHECKED_PORTS="[8140, 45873]"
DOCKER_COMPOSE_NAME=puppet_env
DOCKER_FILES_DIRECTORY=/opt/artix/docker/$DOCKER_COMPOSE_NAME

log() {
    if [[ "TRACE" = "$1" ]] || [[ `(echo "TRACEDEBUGINFOERRORWARN" |sed s/^.*"TRACE"//g )` == *"$1"* ]]; then
        echo "`date '+%Y-%m-%d %H:%M:%S'` $1: $2"
    fi;
}

trim() {
    echo -e "${1}" | tr -d '[[:space:]]'
}
isEmpty() {
    if [[ -z "$(trim "$1")" ]] || [[ -z "$1" ]]; then
        true
    else
        false
    fi;
}
askQuestion() {
    local MSG=`log INFO`

    if (isEmpty $1); then
        MSG="$MSG Do you want to continue (y/n)?"
    else
        MSG="$MSG $1"
    fi

    read -p "$MSG" choice
    case "$choice" in
      y|Y|"" ) true;;
      n|N ) exit 1;;
      * ) false;;
    esac
}
isContainersExist() {
    local NAME="$DOCKER_COMPOSE_NAME"

    sudo docker ps -a | while read line; do
        if [[ ${line} =~ $NAME ]]; then
            echo true
            break
        fi
    done
}

check_ports() {
  if [[ $(sudo fuser 8140/tcp 45873/tcp) ]]; then
      return 1
  else
      return 0
  fi
}

check_exist_certificate(){
    local CERTIFICATE_DIRECTORY="/etc/docker/certs.d"
    if [ -d "$CERTIFICATE_DIRECTORY" ] ;
        then
            log INFO "Directory $CERTIFICATE_DIRECTORY exists."
        else
            log ERROR "Error: Directory with certificate $CERTIFICATE_DIRECTORY not found. Install delivery app stopped."
            exit 1
    fi

    local CERTIFICATE_ARTIX_DIRECTORY="$CERTIFICATE_DIRECTORY/dockerregistry.artix.su:2443"

    if [ -d "$CERTIFICATE_ARTIX_DIRECTORY" ] ;
        then
            log INFO "Directory $CERTIFICATE_ARTIX_DIRECTORY exists."
        else
            log ERROR "Error: Certificate artix not added. Add certificate. Install delivery app stopped."
            exit 1
    fi
}

verify_artix_certificate(){
    local TARGET="dockerregistry.artix.su";
    log INFO "Verify expiration certificate for $TARGET";
    local expirationdate=$(date -d "$(: | openssl s_client -connect $TARGET:2443 -servername $TARGET 2>/dev/null \
                              | openssl x509 -text \
                              | grep 'Not After' \
                              |awk '{print $4,$5,$7}')" '+%s');

    local current_day=$(date +%s);
    if [ $current_day -gt $expirationdate ]; then
        log ERROR "Certificate for $TARGET expires on $(date -d @$expirationdate '+%Y-%m-%d')"
        exit 1;
    else
        log INFO "Certificate expires on $expirationdate";
    fi;
}

set_default_env_variable(){
    local VARIABLE="$1"
    local DEFAULT_VALUE="$2"
    local DESCRIPTION="$3"
    local var
    sudo touch $DOCKER_FILES_DIRECTORY/.env
    grep -q "^${VARIABLE}=" $DOCKER_FILES_DIRECTORY/.env || echo "${VARIABLE}=${DEFAULT_VALUE}"|sudo tee -a $DOCKER_FILES_DIRECTORY/.env
    read -p "Set ${DESCRIPTION}, current value: `grep \"^${VARIABLE}=\" ${DOCKER_FILES_DIRECTORY}/.env`: " var
    if [[ "$var" ]];then
        sudo sed -i "s/^${VARIABLE}=.*/${VARIABLE}=`echo $var|sed 's|/|\\\/|g'`/g" $DOCKER_FILES_DIRECTORY/.env
    fi;
}
check_exist_certificate;
verify_artix_certificate;


log INFO "Start install apt-transport-https, ca-certificates, curl, software-properties-common"

curl ${URL_CS}/extract_gpg_key.sh -o /tmp/extract_gpg_key.sh
. /tmp/extract_gpg_key.sh

sudo apt-get update
sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

vid=$(lsb_release -is)
vid=${vid,,}
log INFO "Add repository deb [arch=amd64] https://download.docker.com/linux/$vid $(lsb_release -cs) stable"
curl -fsSL https://download.docker.com/linux/$vid/gpg | sudo gpg --dearmor > /etc/apt/trusted.gpg.d/docker.gpg -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/$vid \
   $(lsb_release -cs) \
   stable"

log INFO "apt-get update"

sudo apt-get update

log INFO "Start install docker-ce"

sudo apt-get install -y docker-ce

sudo mkdir -p $DOCKER_FILES_DIRECTORY
#Скачаем скрипты для запуска
sudo curl -L ${URL}/docker-compose.yaml -o $DOCKER_FILES_DIRECTORY/docker-compose.yaml

CONTINUE=true
while ${CONTINUE}; do
    res=`isContainersExist`
    if [[ ${res} == true ]]; then
        CONTINUE=`askQuestion "You're already have ${DOCKER_COMPOSE_NAME} containers! Destroy them? (y - continue/n - exit)"`
        if ${CONTINUE}; then
            log INFO "Delete containers:"
            sudo docker rm -f `sudo docker ps -a|grep -a "${DOCKER_COMPOSE_NAME}"|awk '{print $1}'`
            CONTINUE=false;
        fi
    else
        CONTINUE=false;
    fi
done

CONTINUE=true
while ${CONTINUE}; do
    if ! check_ports; then
        log WARN "You're have busy ports. Free up ports: $CHECKED_PORTS. Do it and we will continue!"
    else
        break
    fi
   CONTINUE=`askQuestion "Have you freed the ports? (y - continue/n - exit)"`
done

set_default_env_variable "CS_SERVER_HOST" "$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" "Artix:Cashserver host"

log INFO "Current .env:"
cat $DOCKER_FILES_DIRECTORY/.env

log INFO "Run ${DOCKER_COMPOSE_NAME} services"
(cd $DOCKER_FILES_DIRECTORY && sudo docker compose up -d --build)
log INFO "Your's containers:"
sudo docker ps | grep "${DOCKER_COMPOSE_NAME}"

echo -e '#!/bin/bash\nsudo docker compose stop'|sudo tee $DOCKER_FILES_DIRECTORY/stop > /dev/null && sudo chmod +x $DOCKER_FILES_DIRECTORY/stop
echo -e '#!/bin/bash\nsudo docker compose up -d --build '|sudo tee $DOCKER_FILES_DIRECTORY/start > /dev/null && sudo chmod +x $DOCKER_FILES_DIRECTORY/start
echo -e '#!/bin/bash\n[[ "$1" ]] && sudo docker compose up -d --force-recreate --no-deps $1 || echo "Please set service name as parameter!"'|sudo tee $DOCKER_FILES_DIRECTORY/restart_service > /dev/null \
    && sudo chmod +x $DOCKER_FILES_DIRECTORY/restart_service
echo -e '#!/bin/bash\n[[ "$1" ]] && sudo docker compose exec $@ || echo "Please set service name as parameter!"'|sudo tee $DOCKER_FILES_DIRECTORY/exec_service > /dev/null \
    && sudo chmod +x $DOCKER_FILES_DIRECTORY/exec_service
echo -e '#!/bin/bash\nsudo docker compose logs -f $@'|sudo tee $DOCKER_FILES_DIRECTORY/logs > /dev/null \
    && sudo chmod +x $DOCKER_FILES_DIRECTORY/logs
echo -e '#!/bin/bash\nsudo docker compose ps'|sudo tee $DOCKER_FILES_DIRECTORY/status > /dev/null && sudo chmod +x $DOCKER_FILES_DIRECTORY/status
cat <<EOF|sudo tee $DOCKER_FILES_DIRECTORY/update > /dev/null && sudo chmod +x $DOCKER_FILES_DIRECTORY/update
#!/bin/bash
set -e
cd $DOCKER_FILES_DIRECTORY
sudo echo ""
{
echo "\$(date): check updates"
CURRENT_FILE_NAME="docker-compose.yaml"
NEW_FILE_NAME="\${CURRENT_FILE_NAME}_\$(date +%Y_%M_%d-%s)"
sudo curl -L "${URL}/docker-compose.yaml" -o ./\$NEW_FILE_NAME
if cmp --silent ./\$CURRENT_FILE_NAME ./\$NEW_FILE_NAME; then
    echo "Current version of file is some with downloaded file"
    sudo rm \$NEW_FILE_NAME
else
    echo "copy old version of docker-compose for backup"
    sudo mv ./\$CURRENT_FILE_NAME ./\${CURRENT_FILE_NAME}_\$(date +%Y_%M_%d-%s)_backup
    sudo mv ./\$NEW_FILE_NAME ./\$CURRENT_FILE_NAME
fi
echo "\$(date): check update end"
}|sudo tee -a ./update_info.log
EOF
