#!/usr/bin/env bash
set -euo pipefail

SECRET_FILE="${SFD_SECRET_FILE:-/root/sifangda-project-secrets.env}"
MAIN_ROOT="${SFD_MAIN_ROOT:-/workspace/wwwroot/zhct_sfd/current}"
AI_ROOT="${SFD_AI_ROOT:-/workspace/wwwroot/aizhct_sfd/current}"
MAIN_CONFIG_DIR="$MAIN_ROOT/application/config/prod/zhct_sfd"
AI_ENV_FILE="$AI_ROOT/.env.prodaizhct_sfd"
RENDER_SCOPE="${1:-all}"

if [ "$(id -u)" -ne 0 ]; then
    echo "Run as root after extracting both release packages to current." >&2
    exit 1
fi

if [ ! -f "$SECRET_FILE" ]; then
    echo "Secret parameter file is missing: $SECRET_FILE" >&2
    exit 1
fi

if [ "$(stat -c '%a' "$SECRET_FILE")" != "600" ]; then
    echo "Secret parameter file must have mode 600: $SECRET_FILE" >&2
    exit 1
fi

set -a
# shellcheck disable=SC1090
source "$SECRET_FILE"
set +a

if [ "$RENDER_SCOPE" != "main" ] && [ "$RENDER_SCOPE" != "ai" ] && [ "$RENDER_SCOPE" != "all" ]; then
    echo "Usage: $0 [main|ai|all]" >&2
    exit 2
fi

common_variables=(
    SFD_APP_SERVER_IP
    SFD_DB_SERVER_IP
    SFD_DB_USERNAME
    SFD_DB_PASSWORD
    SFD_REDIS_PASSWORD
)
required_variables=("${common_variables[@]}")
for variable_name in "${required_variables[@]}"; do
    if [ -z "${!variable_name:-}" ]; then
        echo "Required private parameter is empty: $variable_name" >&2
        exit 1
    fi
    if [[ "${!variable_name}" == __*__ ]]; then
        echo "Required private parameter is still pending: $variable_name" >&2
        exit 1
    fi
done

for ip_variable in SFD_APP_SERVER_IP SFD_DB_SERVER_IP; do
    if ! [[ "${!ip_variable}" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
        echo "$ip_variable is not an IPv4 address." >&2
        exit 1
    fi
done

if ! [[ "$SFD_DB_USERNAME" =~ ^[A-Za-z0-9_]{1,16}$ ]]; then
    echo "SFD_DB_USERNAME must be a MySQL 5.6 compatible account name." >&2
    exit 1
fi

for secret_variable in SFD_DB_PASSWORD SFD_REDIS_PASSWORD; do
    secret_value="${!secret_variable}"
    if [ "${#secret_value}" -lt 8 ]; then
        echo "$secret_variable is too short." >&2
        exit 1
    fi
    if [[ "$secret_value" == *$'\n'* ]] || [[ "$secret_value" == *$'\r'* ]]; then
        echo "$secret_variable must not contain a line break." >&2
        exit 1
    fi
done

required_targets=()
if [ "$RENDER_SCOPE" = "main" ] || [ "$RENDER_SCOPE" = "all" ]; then
    required_targets+=(
        "$MAIN_CONFIG_DIR/config.php"
        "$MAIN_CONFIG_DIR/database.php"
    )
fi
if [ "$RENDER_SCOPE" = "ai" ] || [ "$RENDER_SCOPE" = "all" ]; then
    required_targets+=("$AI_ENV_FILE")
fi
for target in "${required_targets[@]}"; do
    if [ ! -f "$target" ]; then
        echo "Release configuration file is missing: $target" >&2
        exit 1
    fi
done

export MAIN_CONFIG_DIR AI_ENV_FILE RENDER_SCOPE

/usr/local/php7.3/bin/php -r '
function php_single_quoted_value($value) {
    return str_replace(["\\", "'\''"], ["\\\\", "\\'\''"], $value);
}
function ini_quoted_value($value) {
    return "\"" . str_replace(["\\", "\"", "\r", "\n"], ["\\\\", "\\\"", "", ""], $value) . "\"";
}
function render_file($path, array $tokens) {
    $content = file_get_contents($path);
    if ($content === false) {
        fwrite(STDERR, "Cannot read release configuration: {$path}\n");
        exit(1);
    }
    $content = str_replace(array_keys($tokens), array_values($tokens), $content);
    if (file_put_contents($path, $content, LOCK_EX) === false) {
        fwrite(STDERR, "Cannot write release configuration: {$path}\n");
        exit(1);
    }
}
$scope = getenv("RENDER_SCOPE");
$optional = static function ($name) {
    $value = getenv($name);
    return $value === false ? "" : $value;
};
$phpTokens = [
    "__SFD_APP_SERVER_IP__" => php_single_quoted_value(getenv("SFD_APP_SERVER_IP")),
    "__SFD_DB_SERVER_IP__" => php_single_quoted_value(getenv("SFD_DB_SERVER_IP")),
    "__SFD_DB_USERNAME__" => php_single_quoted_value(getenv("SFD_DB_USERNAME")),
    "__SFD_DB_PASSWORD__" => php_single_quoted_value(getenv("SFD_DB_PASSWORD")),
    "__SFD_REDIS_PASSWORD__" => php_single_quoted_value(getenv("SFD_REDIS_PASSWORD")),
    "__SFD_WX_APPID__" => php_single_quoted_value($optional("SFD_WX_APPID")),
    "__SFD_WX_APPSECRET__" => php_single_quoted_value($optional("SFD_WX_APPSECRET")),
    "__SFD_MINIPROGRAM_APPID__" => php_single_quoted_value($optional("SFD_MINIPROGRAM_APPID")),
    "__SFD_MINIPROGRAM_SECRET__" => php_single_quoted_value($optional("SFD_MINIPROGRAM_SECRET")),
    "__SFD_LOCK_LYG_APP_VERSION__" => php_single_quoted_value($optional("SFD_LOCK_LYG_APP_VERSION")),
];
$iniTokens = [
    "__SFD_APP_SERVER_IP__" => getenv("SFD_APP_SERVER_IP"),
    "__SFD_DB_SERVER_IP__" => getenv("SFD_DB_SERVER_IP"),
    "__SFD_DB_USERNAME__" => ini_quoted_value(getenv("SFD_DB_USERNAME")),
    "__SFD_DB_PASSWORD__" => ini_quoted_value(getenv("SFD_DB_PASSWORD")),
    "__SFD_REDIS_PASSWORD__" => ini_quoted_value(getenv("SFD_REDIS_PASSWORD")),
];
if ($scope === "main" || $scope === "all") {
    render_file(getenv("MAIN_CONFIG_DIR") . "/config.php", $phpTokens);
    render_file(getenv("MAIN_CONFIG_DIR") . "/database.php", $phpTokens);
}
if ($scope === "ai" || $scope === "all") {
    render_file(getenv("AI_ENV_FILE"), $iniTokens);
}
'

chmod 0640 "${required_targets[@]}"
chown www:www "${required_targets[@]}"

if grep -RInE '__SFD_[A-Z0-9_]+__' "${required_targets[@]}"; then
    echo "Unresolved Sifangda placeholder remains in rendered project configuration." >&2
    exit 1
fi

if grep -RInE 'zhct_bzjk|aizhct_bzjk|bziht|10\.10\.12\.|yyangpt|kxunpt' \
    "${required_targets[@]}"; then
    echo "Cross-customer residue found in rendered project configuration." >&2
    exit 1
fi

if [ "$RENDER_SCOPE" = "main" ] || [ "$RENDER_SCOPE" = "all" ]; then
    /usr/local/php7.3/bin/php -l "$MAIN_CONFIG_DIR/config.php"
    /usr/local/php7.3/bin/php -l "$MAIN_CONFIG_DIR/database.php"
fi

echo "Sifangda release configuration rendered in current: $RENDER_SCOPE"
echo "No secret value was printed. Review the masked configuration, then publish current to project."
