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

DIVISIONDESK_URL="${DIVISIONDESK_URL:-https://divisiondesk.com}"
MANIFEST_URL="${DIVISIONDESK_MANIFEST_URL:-$DIVISIONDESK_URL/releases/core/latest.json}"
TARGET="${DIVISIONDESK_TARGET:-$(pwd)}"
SELF="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"

echo "DivisionDesk Installer"
echo "======================"
echo

command -v php >/dev/null 2>&1 || { echo "ERROR: PHP CLI is required."; exit 1; }
command -v curl >/dev/null 2>&1 || { echo "ERROR: curl is required."; exit 1; }

PHP_VERSION="$(php -r 'echo PHP_VERSION;')"
echo "✓ PHP $PHP_VERSION detected"

if [ -f "$TARGET/storage/setup/installed.lock" ]; then
  echo "ERROR: DivisionDesk is already installed in $TARGET"
  echo "Use the Core updater/repair tools instead of the bootstrap installer."
  exit 1
fi

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

echo "Checking latest Core release..."
curl -fsSL "$MANIFEST_URL" -o "$TMP/latest.json"

readarray -t META < <(php -r '
$m=json_decode(file_get_contents($argv[1]),true);
if(!is_array($m)){fwrite(STDERR,"ERROR: Release manifest is not valid JSON.\n");exit(2);}
$version=(string)($m["version"]??"");
$url=(string)($m["package_url"]??($m["download"]??""));
$sha=(string)($m["sha256"]??($m["checksum"]["value"]??""));
$min=(string)($m["minimum_php"]??"8.1");
$size=(int)($m["package_size"]??0);
$minInstaller=(string)($m["installer"]["minimum_api"]??"1");
if($version===""||!preg_match("#^https://#i",$url)||!preg_match("/^[a-f0-9]{64}$/i",$sha)||$size<1){
 fwrite(STDERR,"ERROR: Release manifest is incomplete.\n");exit(3);
}
if(version_compare(PHP_VERSION,$min,"<")){fwrite(STDERR,"ERROR: Core requires PHP ".$min." or newer.\n");exit(4);}
if(version_compare("2",$minInstaller,"<")){fwrite(STDERR,"ERROR: This DivisionDesk-install bootstrap is too old for the current Core package.\n");exit(5);}
echo $version."\n".$url."\n".$sha."\n".$min."\n".$size."\n";
' "$TMP/latest.json")

VERSION="${META[0]}"
PACKAGE_URL="${META[1]}"
EXPECTED_SHA="${META[2]}"
MIN_PHP="${META[3]}"
EXPECTED_SIZE="${META[4]}"

echo "✓ Current Core: $VERSION"
echo "Downloading Core package..."
curl -fL --retry 3 --connect-timeout 15 "$PACKAGE_URL" -o "$TMP/core.zip"

ACTUAL_SIZE="$(php -r 'echo filesize($argv[1]);' "$TMP/core.zip")"
[ "$ACTUAL_SIZE" = "$EXPECTED_SIZE" ] || { echo "ERROR: Downloaded package size does not match release manifest."; exit 1; }

ACTUAL_SHA="$(php -r 'echo hash_file("sha256",$argv[1]);' "$TMP/core.zip")"
[ "${ACTUAL_SHA,,}" = "${EXPECTED_SHA,,}" ] || { echo "ERROR: SHA-256 verification failed."; exit 1; }
echo "✓ SHA-256 verified"

mkdir -p "$TARGET"

php -r '
if(!class_exists("ZipArchive")){fwrite(STDERR,"ERROR: PHP ZipArchive extension is required.\n");exit(2);}
$zip=new ZipArchive;
if($zip->open($argv[1])!==true){fwrite(STDERR,"ERROR: Could not open Core ZIP.\n");exit(3);}
for($i=0;$i<$zip->numFiles;$i++){
 $n=(string)$zip->getNameIndex($i);
 if($n===""||str_contains($n,"../")||str_contains($n,"..\\")||str_starts_with($n,"/")||preg_match("/^[A-Za-z]:[\\\\\/]/",$n)){fwrite(STDERR,"ERROR: Unsafe path in Core ZIP: ".$n."\n");$zip->close();exit(5);}
 $ops=0;$attr=0;if($zip->getExternalAttributesIndex($i,$ops,$attr)&&$ops===ZipArchive::OPSYS_UNIX){$mode=($attr>>16)&0170000;if($mode===0120000){fwrite(STDERR,"ERROR: Symlinks are not allowed in Core ZIP.\n");$zip->close();exit(6);}}
}
if(!$zip->extractTo($argv[2])){fwrite(STDERR,"ERROR: Could not extract Core ZIP.\n");exit(4);}
$zip->close();
' "$TMP/core.zip" "$TARGET"

mkdir -p "$TARGET/storage/setup" "$TARGET/storage/logs" "$TARGET/storage/updates" "$TARGET/storage/data"
chmod -R u+rwX,g+rwX "$TARGET/storage" 2>/dev/null || true
find "$TARGET" -type d -exec chmod 775 {} \; 2>/dev/null || true
find "$TARGET" -type f -exec chmod 664 {} \; 2>/dev/null || true
find "$TARGET/bin" -type f -exec chmod 775 {} \; 2>/dev/null || true

TOKEN="$(php -r 'echo bin2hex(random_bytes(24));')"
printf '%s' "$TOKEN" > "$TARGET/storage/setup/token"
chmod 600 "$TARGET/storage/setup/token" 2>/dev/null || true

php -r '
$marker=$argv[1]."/storage/setup/installer-cleanup.json";
$data=["path"=>$argv[2],"created_at"=>date(DATE_ATOM)];
file_put_contents($marker,json_encode($data,JSON_UNESCAPED_SLASHES),LOCK_EX);
' "$TARGET" "$SELF"

echo "✓ Core $VERSION installed"
echo
echo "Browser setup is ready."
if [ -n "${DIVISIONDESK_SITE_URL:-}" ]; then
  BASE="${DIVISIONDESK_SITE_URL%/}"
  echo "Open: $BASE/public/setup.php?token=$TOKEN"
else
  echo "Open your site's /public/setup.php?token=$TOKEN URL."
fi
echo
echo "The installer bootstrap will remove/disable itself after setup completes successfully."
