#!/usr/bin/env bash

set -e

# This file is using docker to run commands
SPC_DOCKER_VERSION=v6

# Detect docker can run
if ! which docker >/dev/null; then
    echo "Docker is not installed, please install docker first !"
    exit 1
fi
DOCKER_EXECUTABLE="docker"
# shellcheck disable=SC2046
if [ $(id -u) -ne 0 ]; then
    if ! docker info > /dev/null 2>&1; then
        if [ "$SPC_USE_SUDO" != "yes" ]; then
            echo "Docker command requires sudo"
            # shellcheck disable=SC2039
            echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
            exit 1
        fi
        DOCKER_EXECUTABLE="sudo docker"
    fi
fi

# Convert uname to gnu arch
CURRENT_ARCH=$(uname -m)
if [ "$CURRENT_ARCH" = "arm64" ]; then
    CURRENT_ARCH=aarch64
fi
if [ -z "$SPC_USE_ARCH" ]; then
    SPC_USE_ARCH=$CURRENT_ARCH
fi
# parse SPC_USE_ARCH
case $SPC_USE_ARCH in
x86_64|amd64)
    SPC_USE_ARCH=x86_64
    if [ "$CURRENT_ARCH" != "x86_64" ]; then
        PLATFORM_ARG="--platform linux/amd64"
        ALPINE_FROM=multiarch/alpine:x86_64-edge
    fi
    ;;
aarch64|arm64)
    SPC_USE_ARCH=aarch64
    if [ "$CURRENT_ARCH" != "aarch64" ]; then
        PLATFORM_ARG="--platform linux/arm64"
        ALPINE_FROM=multiarch/alpine:aarch64-edge
    fi
    ;;
*)
    echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
    exit 1
    ;;
esac
# if ALPINE_FROM is not set, use alpine:3.21
if [ -z "$ALPINE_FROM" ]; then
    ALPINE_FROM=alpine:3.21
fi
if [ "$SPC_USE_ARCH" != "$CURRENT_ARCH" ]; then
    echo "* Using different arch needs to setup qemu-static for docker !"
    ALPINE_FROM=multiarch/alpine:$SPC_USE_ARCH-edge
    if [ "$(uname -s)" = "Linux" ]; then
        $DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
    fi
else
    ALPINE_FROM=alpine:3.21
fi

if [ "$SPC_USE_MIRROR" = "yes" ]; then
    SPC_USE_MIRROR="RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories"
else
    SPC_USE_MIRROR="RUN echo 'Using original repo'"
fi

# Detect docker env is setup
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION; then
    echo "Docker container does not exist. Building docker image ..."
    $DOCKER_EXECUTABLE build $PLATFORM_ARG -t cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION -f- . <<EOF
FROM $ALPINE_FROM
$SPC_USE_MIRROR
RUN apk update; \
    apk upgrade -a; \
    apk add --no-cache \
        autoconf \
        automake \
        gettext \
        bash \
        binutils \
        bison \
        build-base \
        cmake \
        curl \
        file \
        flex \
        g++ \
        gcc \
        git \
        jq \
        libgcc \
        libtool \
        libstdc++ \
        linux-headers \
        m4 \
        make \
        pkgconfig \
        re2c \
        wget \
        xz \
        gettext-dev \
        binutils-gold

RUN curl -#fSL https://dl.static-php.dev/static-php-cli/bulk/php-8.4.4-cli-linux-\$(uname -m).tar.gz | tar -xz -C /usr/local/bin && \
    chmod +x /usr/local/bin/php

RUN curl -#fSL https://getcomposer.org/download/latest-stable/composer.phar -o /usr/local/bin/composer && \
    chmod +x /usr/local/bin/composer

WORKDIR /app
ADD ./src /app/src
COPY ./composer.* /app/
ADD ./bin /app/bin
RUN composer install --no-dev
ADD ./config /app/config
RUN bin/spc doctor --auto-fix
RUN bin/spc install-pkg upx

RUN mv /app/pkgroot/\$(uname -m)-linux /app/pkgroot-private
ADD bin/docker-entrypoint.sh /bin/docker-entrypoint.sh
RUN chmod +x /bin/docker-entrypoint.sh
ENTRYPOINT ["/bin/docker-entrypoint.sh"]
EOF
fi

# Check if in ci (local terminal can execute with -it)
if [ -t 0 ]; then
    INTERACT=-it
else
    INTERACT=''
fi

# Mounting volumes
MOUNT_LIST=""
# shellcheck disable=SC2089
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/log:/app/log"
if [ -f "$(pwd)/craft.yml" ]; then
    MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/craft.yml:/app/craft.yml"
fi

# Environment variable passthrough
ENV_LIST=""
ENV_LIST="$ENV_LIST -e SPC_FIX_DEPLOY_ROOT="$(pwd)""
if [ ! -z "$GITHUB_TOKEN" ]; then
    ENV_LIST="$ENV_LIST -e GITHUB_TOKEN=$GITHUB_TOKEN"
fi

# Intercept and rewrite --with-frankenphp-app option, and mount host path to /app/app
FRANKENPHP_APP_PATH=""
NEW_ARGS=()
while [ $# -gt 0 ]; do
    case "$1" in
        --with-frankenphp-app=*)
            FRANKENPHP_APP_PATH="${1#*=}"
            NEW_ARGS+=("--with-frankenphp-app=/app/app")
            shift
            ;;
        --with-frankenphp-app)
            if [ -n "${2:-}" ]; then
                FRANKENPHP_APP_PATH="$2"
                NEW_ARGS+=("--with-frankenphp-app=/app/app")
                shift 2
            else
                NEW_ARGS+=("$1")
                shift
            fi
            ;;
        *)
            NEW_ARGS+=("$1")
            shift
            ;;
    esac
done

# Normalize the path and add mount if provided
if [ -n "$FRANKENPHP_APP_PATH" ]; then
    # expand ~ to $HOME
    if [ "${FRANKENPHP_APP_PATH#~}" != "$FRANKENPHP_APP_PATH" ]; then
        FRANKENPHP_APP_PATH="$HOME${FRANKENPHP_APP_PATH#~}"
    fi
    # make absolute if relative
    case "$FRANKENPHP_APP_PATH" in
        /*) ABS_APP_PATH="$FRANKENPHP_APP_PATH" ;;
        *) ABS_APP_PATH="$(pwd)/$FRANKENPHP_APP_PATH" ;;
    esac
    MOUNT_LIST="$MOUNT_LIST -v $ABS_APP_PATH:/app/app"
fi

# Run docker
# shellcheck disable=SC2068
# shellcheck disable=SC2086
# shellcheck disable=SC2090
if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
    echo "* Debug mode enabled, run docker in interactive mode."
    echo "* You can use 'exit' to exit the docker container."
    echo "* You can use 'bin/spc' like normal builds."
    echo "*"
    echo "*    Mounted directories:"
    echo "*    ./config:    $(pwd)/config"
    echo "*    ./src:       $(pwd)/src"
    echo "*    ./buildroot: $(pwd)/buildroot"
    echo "*    ./source:    $(pwd)/source"
    echo "*    ./dist:      $(pwd)/dist"
    echo "*    ./downloads: $(pwd)/downloads"
    echo "*    ./pkgroot:   $(pwd)/pkgroot"
    echo "*"
    set -ex
    $DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION /bin/bash
else
    $DOCKER_EXECUTABLE run $PLATFORM_ARG --rm $INTERACT $ENV_LIST $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-$SPC_DOCKER_VERSION bin/spc "${NEW_ARGS[@]}"
fi
