#!/bin/sh

# Parameters
REVISION="$1"
if echo "$GIMP_CI_MACOS" | grep -q '[1-9]' && [ "$CI_PIPELINE_SOURCE" != 'schedule' ]; then
  export REVISION="$GIMP_CI_MACOS"
fi
BUILD_DIR="$2"
ARM64_BUNDLE=${3:-gimp-arm64.app}
X86_64_BUNDLE=${4:-gimp-x86_64.app}

# Ensure the script work properly
case $(readlink /proc/$$/exe) in
  *bash)
    set -o posix
    ;;
esac
set -e
if [ "$0" != 'build/macos/dmg/3_dist-gimp-apple.sh' ] && [ $(basename "$PWD") != 'dmg' ]; then
  printf '\033[31m(ERROR)\033[0m: Script called from wrong dir. Please, call this script from the root of gimp source dir\n'
  exit 1
elif [ $(basename "$PWD") = 'dmg' ]; then
  cd ../../..
fi


# 1. GET MACOS TOOLS VERSION
printf "\e[0Ksection_start:`date +%s`:mac_tlkt\r\e[0KChecking macOS tools\n"
printf "(INFO): macOS version: $(sw_vers -productVersion) | Python version: $(python3 --version 2>&1 | sed 's/[^0-9.]//g')\n"
printf "\e[0Ksection_end:`date +%s`:mac_tlkt\r\e[0K\n"


# 2. GLOBAL INFO
printf "\e[0Ksection_start:`date +%s`:mac_info\r\e[0KGetting DMG global info\n"
if [ "$BUILD_DIR" = '' ]; then
  export BUILD_DIR=$(find $PWD -maxdepth 1 -iname "_build*$(uname -m)" | head -n 1)
fi
if [ ! -f "$BUILD_DIR/config.h" ]; then
  printf "\033[31m(ERROR)\033[0m: config.h file not found. You can configure GIMP with meson to generate it.\n"
  exit 1
fi
eval $(sed -n 's/^#define  *\([^ ]*\)  *\(.*\) *$/export \1=\2/p' $BUILD_DIR/config.h)

# Set proper identifier and bundle name
if [ -z "$GIMP_RELEASE" ] || [ -n "$GIMP_IS_RC_GIT" ]; then
  BUNDLE_IDENTIFIER="org.gimp.gimp.internal"
  BUNDLE_NAME="GIMP (Nightly)"
elif { [ -n "$GIMP_RELEASE" ] && [ -n "$GIMP_UNSTABLE" ]; } || [ -n "$GIMP_RC_VERSION" ]; then
  BUNDLE_IDENTIFIER="org.gimp.gimp.seed"
  BUNDLE_NAME="GIMP (Beta)"
  MUTEX_SUFFIX="-${GIMP_MUTEX_VERSION}"
else
  BUNDLE_IDENTIFIER="org.gimp.gimp"
  BUNDLE_NAME="GIMP"
  MUTEX_SUFFIX="-${GIMP_MUTEX_VERSION}"
fi

## Get info about GIMP version
export CUSTOM_GIMP_VERSION=$(echo $GIMP_VERSION | tr -d '\r')
if ! echo "$REVISION" | grep -q '[1-9]'; then
  export REVISION="0"
else
  export CUSTOM_GIMP_VERSION="${GIMP_VERSION}-${REVISION}"
fi
printf "(INFO): .app namespace: ${BUNDLE_NAME} | Version: $CUSTOM_GIMP_VERSION\n"

## Autodetects what archs will be packaged
if [ ! -d "$ARM64_BUNDLE" ] && [ ! -d "$X86_64_BUNDLE" ]; then
    printf "\033[31m(ERROR)\033[0m: No bundle found. You can tweak 'build/macos/2_build-gimp-macports.sh' or configure GIMP with '-Ddmg=true' to make one.\n"
    exit 1
elif [ -d "$ARM64_BUNDLE" ] && [ ! -d "$X86_64_BUNDLE" ]; then
    printf '(INFO): Arch: arm64\n'
    supported_archs="$ARM64_BUNDLE"
elif [ ! -d "$ARM64_BUNDLE" ] && [ -d "$X86_64_BUNDLE" ]; then
    printf '(INFO): Arch: x86_64'
    supported_archs="$X86_64_BUNDLE"
elif [ -d "$ARM64_BUNDLE" ] && [ -d "$X86_64_BUNDLE" ]; then
    printf '(INFO): Arch: arm64 and x86_64'
    supported_archs="$ARM64_BUNDLE $X86_64_BUNDLE"
fi
printf "\e[0Ksection_end:`date +%s`:mac_info\r\e[0K\n"


# 3. PREPARE FILES
for APP in $(echo "$supported_archs" | tr ' ' '\n'); do
export ARCH=$(echo $APP | sed -e 's|gimp-||' -e 's|./||' -e 's|.app||')
printf "\e[0Ksection_start:`date +%s`:${ARCH}_files[collapsed=true]\r\e[0KPreparing GIMP files in $ARCH .dmg\n"
## Create temporary .dmg
APPVER="GIMP $CUSTOM_GIMP_VERSION install"
hdiutil create -volname "$APPVER" -srcfolder "$APP" -ov -format UDRW "temp_$ARCH.dmg"
#(we do not use 'hdiutil attach -mountrandom' because dangling mounts would last if the script fails)
existing_dmg_mount=$(hdiutil info | grep "$APPVER" | cut -f3-)
if [ -d "$existing_dmg_mount" ]; then
  hdiutil detach "$existing_dmg_mount" -force
fi
DMG_MOUNT=$(hdiutil attach "temp_$ARCH.dmg" | grep "$APPVER" | cut -f3-)
mv -f "$DMG_MOUNT/$APP" "$DMG_MOUNT/$BUNDLE_NAME.app"

## Set revision (this does the same as '-Drevision' build option)
gimp_release="$(echo "$DMG_MOUNT/$BUNDLE_NAME.app"/Contents/Resources/gimp/*/gimp-release)"
before=$(cat "$gimp_release" | grep 'revision')
after="revision=$REVISION"
sed -i '' "s|$before|$after|" "$gimp_release"

## Minor adjustments
rm -f "$DMG_MOUNT/$BUNDLE_NAME.app/.gitignore"
printf "\e[0Ksection_end:`date +%s`:${ARCH}_files\r\e[0K\n"


# 4. CREATE ASSETS
printf "\e[0Ksection_start:`date +%s`:${ARCH}_source[collapsed=true]\r\e[0KMaking .dmg assets for $ARCH .dmg\n"
# (We test the existence of the background here (and not on section 4.2.) to avoid configuring Info.plist for nothing)
BG_PATH="$BUILD_DIR/gimp-data/images/logo/gimp-dmg.png"
if [ ! -f "$BG_PATH" ]; then
  printf "\033[31m(ERROR)\033[0m: DMG background image not found. You can tweak 'build/macos/2_build-gimp-macports.sh' or configure GIMP with '-Ddmg=true' to build it.\n"
  exit 1
fi

## 4.1 Configure Info.plist
printf '(INFO): configuring Info.plist\n'
conf_plist()
{
  sed -i '' "s|$1|$2|g" "$DMG_MOUNT/$BUNDLE_NAME.app/Contents/Info.plist"
}
### Set Identifier
conf_plist "%BUNDLE_IDENTIFIER%" "$BUNDLE_IDENTIFIER"
### Set Name (the name shown on Finder etc)
conf_plist "%BUNDLE_NAME%" "$BUNDLE_NAME"
### Set custom GIMP version
conf_plist "%GIMP_VERSION%" "$CUSTOM_GIMP_VERSION"
#### Needed to differentiate on zsh etc
conf_plist "%MUTEX_SUFFIX%" "$MUTEX_SUFFIX"
### List supported filetypes
sed -i '' "s|%FILE_TYPES%|$(tr -d '\n' < $BUILD_DIR/plug-ins/file_associations_mac.list)|g" "$DMG_MOUNT/$BUNDLE_NAME.app/Contents/Info.plist"

## 4.2 Create or copy .DS_Store to set .dmg background and icon layout
printf '(INFO): generating .DS_Store\n'
cp -r "$BG_PATH" "$DMG_MOUNT/.background.png"
ln -s /Applications "$DMG_MOUNT/Applications"
#Ported from https://github.com/salty-salty-studios/first-snow/blob/main/installer/mac/metabuilder.py
python3 -m venv ds-py3-venv
. ds-py3-venv/bin/activate
pip install ds_store biplist mac_alias
python3 <<-EOF
from datetime import datetime, timezone
import ds_store
import biplist
import mac_alias

def create_alias(volname, filename):
  volume = mac_alias.VolumeInfo(
    volname, datetime.now(timezone.utc),
    fs_type=mac_alias.ALIAS_HFS_VOLUME_SIGNATURE, disk_type=mac_alias.ALIAS_FIXED_DISK,
    attribute_flags=0, fs_id=bytes(2),
  )
  target = mac_alias.TargetInfo(
    mac_alias.ALIAS_KIND_FILE, filename,
    folder_cnid=0, cnid=0, creation_date=datetime.now(timezone.utc),
    creator_code=bytes(4), type_code=bytes(4),
    folder_name=volname, carbon_path='{}:{}'.format(volname, filename),
  )
  return mac_alias.Alias(volume=volume, target=target)

if __name__ == '__main__':
  store = ds_store.DSStore.open("$DMG_MOUNT/.DS_Store", 'w+')
  store['.']['vSrn'] = ('long', 1)
  store['.']['icvl'] = ('type', 'icnv')

  #background
  icvp_options = {
    'backgroundType': 2,
    'backgroundColorRed': 1.0,
    'backgroundColorGreen': 1.0,
    'backgroundColorBlue': 1.0,
    'backgroundImageAlias': biplist.Data(create_alias("$APPVER", ".background.png").to_bytes()),
  }
  bwsp_options = {
    'WindowBounds': '{{100, 100}, {%s, %s}}' % (640, 512),
    'ShowToolbar': False,
    'ShowPathbar': False,
    'ShowStatusBar': False,
  }

  #icons
  icvp_options.update({
    'viewOptionsVersion': 1,
    'gridSpacing': 100.0,
    'gridOffsetX': 0.0,
    'gridOffsetY': 0.0,
    'scrollPositionY': 0.0,
    'arrangeBy': 'none',
    'labelOnBottom': True,
    'showItemInfo': False,
    'showIconPreview': False,
    'iconSize': 110.0,
    'textSize': 16.0,
  })
  store["$BUNDLE_NAME.app"]['Iloc'] = (192, 282)
  store["Applications"]['Iloc'] = (448, 282)
  store['.background.png']['Iloc'] = (524, 0)
  store['.fseventsd']['Iloc'] = (524, 0)

  store['.']['icvp'] = icvp_options
  store['.']['bwsp'] = bwsp_options
  store.close()
EOF
rm -fr ds-py3-venv
#Works only interactively
#if [ -z "$GITLAB_CI" ]; then
#  sync
#  sleep 2 #avoid Finder async issues
#  osascript <<EOF
#tell application "Finder"
#    tell disk "$APPVER"
#        open
#        -- background
#        set bounds of container window to {1, 1, 641, 512}
#        set background picture of icon view options of container window to POSIX file "$DMG_MOUNT/.background.png"
#        set toolbar visible of container window to false
#        set pathbar visible of container window to false
#        set statusbar visible of container window to false
#        -- icons
#        set current view of container window to icon view
#        set arrangement of icon view options of container window to not arranged
#        set icon size of icon view options of container window to 110
#        set text size of icon view options of container window to 16
#        set position of item "$BUNDLE_NAME.app" of container window to {192, 282}
#        set position of item "Applications" of container window to {448, 282}
#        set position of item ".background.png" of container window to {545, 0}
#        set position of item ".fseventsd" of container window to {545, 0}
#        update without registering applications
#        close
#    end tell
#end tell
#EOF

## 4.3 Set custom .VolumeIcon.icns
printf '(INFO): copying .VolumeIcon.icns\n'
cp "$BUILD_DIR/build/macos/.VolumeIcon.icns" "$DMG_MOUNT"
SetFile -c icnC "$DMG_MOUNT/.VolumeIcon.icns"
SetFile -a C "$DMG_MOUNT"
hdiutil detach "$DMG_MOUNT"
printf "\e[0Ksection_end:`date +%s`:${ARCH}_source\r\e[0K\n"


# 5. FINISH .DMG AS COMPRESSED READ-ONLY
DMG_ARTIFACT="gimp-${CUSTOM_GIMP_VERSION}-${ARCH}.dmg"
printf "\e[0Ksection_start:`date +%s`:${ARCH}_making[collapsed=true]\r\e[0KCompressing %s\n" ${DMG_ARTIFACT}
hdiutil convert "temp_$ARCH.dmg" -format ULFO -o "$DMG_ARTIFACT"
rm "temp_$ARCH.dmg"
printf "\e[0Ksection_end:`date +%s`:${ARCH}_making\r\e[0K\n"


# 6.A NOTARIZE .APP (TODO)


# 6.B GENERATE SHASUMS FOR .DMG
printf "\e[0Ksection_start:`date +%s`:${ARCH}_trust[collapsed=true]\r\e[0KChecksumming ${DMG_ARTIFACT}\n"
printf "(INFO): ${DMG_ARTIFACT} SHA-256: $(shasum -a 256 ${DMG_ARTIFACT} | cut -d ' ' -f 1)\n"
printf "(INFO): ${DMG_ARTIFACT} SHA-512: $(shasum -a 512 ${DMG_ARTIFACT} | cut -d ' ' -f 1)\n"
printf "\e[0Ksection_end:`date +%s`:${ARCH}_trust\r\e[0K\n"


if [ "$GITLAB_CI" ]; then
  output_dir='build/macos/dmg/_Output'
  mkdir -p $output_dir
  mv -f ${DMG_ARTIFACT} $output_dir
fi
done