#!/usr/bin/env -S sh -euo pipefail

#
# Copyright (C) 2019, 2023  VHS <vhsdev@tutanota.com>
#
# This file is part of After Dark.
#
# After Dark is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# After Dark is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#

vers() { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
parse_hugo_vers() {
   hugovers=$(hugo version | sed 's/-.*//')
   hugovers="${hugovers#"${hugovers%%[0-9]*}"}"
   HUGO_VERSION=${hugovers}
}

validate_hugo() {
   # Exit with error if hugo is not installed
   if ! hash hugo 2>/dev/null; then
      echo "Error: After Dark requires Hugo version 0.51 or greater" >&2
      exit 1
   fi

   # Exit with error if not minimum required hugo version
   parse_hugo_vers
   if [ "$(vers "$HUGO_VERSION")" -lt "$(vers "0.51")" ]; then
      echo "Error: After Dark requires Hugo version 0.51 or greater"
      exit 1
   fi
}

confirm_intent() {
   while true; do
      printf "Do you wish to install After Dark? (y/n) "
      read -r yn </dev/tty
      case $yn in
      [Yy]*)
         break
         ;;
      [Nn]*) exit ;;
      *) echo "Please answer yes or no." ;;
      esac
   done
}

set_default_site_name() {
   SITE_NAME="Flying Toasters"
}

prompt_site_name() {
   printf "Please enter a name for your site: "
   read -r response </dev/tty
   SITE_NAME="$(echo "$response" | tr -cd '[:alnum:] [:space:]' | tr -s '[:space:]')"
   while true; do
      printf "You entered %s. Is that correct? (y/n) " "\"$SITE_NAME\""
      read -r yn </dev/tty
      case $yn in
      [Yy]*)
         break
         ;;
      [Nn]*)
         prompt_site_name
         break
         ;;
      *) echo "Please answer yes or no." ;;
      esac
   done
}

format_dir_name() {
   echo "$1" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' | tr -cd '[:alnum:]._-'
}

set_default_install_dir() {
   SITE_DIR="$(format_dir_name "$SITE_NAME")"
}

prompt_install_dir() {
   default_dir="$(format_dir_name "$SITE_NAME")"
   printf "Choose an installation directory name (%s): " "$default_dir"
   read -r response </dev/tty
   if [ "$response" = "" ]; then
      SITE_DIR=$default_dir
   elif [ "${response%"${response#?}"}" = "/" ]; then
      echo "Directory name not allowed. Proceeding with default..."
      SITE_DIR=$default_dir
   else
      formatted_input_dir=$(format_dir_name "$response")
      if [ "$formatted_input_dir" = "" ]; then
         echo "Directory name not allowed. Proceeding with default..."
         SITE_DIR=$default_dir
      else
         SITE_DIR=$formatted_input_dir
      fi
   fi
   while true; do
      printf "Installation directory name set to %s. Is that correct? (y/n) " "\"$SITE_DIR\""
      read -r yn </dev/tty
      case $yn in
      [Yy]*)
         break
         ;;
      [Nn]*)
         prompt_install_dir
         break
         ;;
      *) echo "Please answer yes or no." ;;
      esac
   done
}

create_site_dir() {
   SITE_DIR_ABS="$PWD/$SITE_DIR"
   mkdir "$SITE_DIR"
}

create_site() {
   echo "Creating a new Hugo site ..."
   hugo new site "$SITE_DIR" 1>/dev/null
   cd "$SITE_DIR" || exit 1
}

download_theme() {
   echo "Downloading the latest version of After Dark ..."
   LATEST_META=$(wget -qO- https://registry.npmjs.org/after-dark/latest)
   vers=$(echo "$LATEST_META" | grep -oE "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
   mkdir -p themes/after-dark
   wget -qO- https://registry.npmjs.org/after-dark/-/after-dark-"$vers".tgz | tar --strip-components=1 -xz -C themes/after-dark
   echo "Version $vers downloaded to $SITE_DIR/themes/after-dark"
}

download_module() {
   [ -z "$1" ] && {
      echo "Error: Attempt to download undefined module" >&2
      exit 1
   }
   echo "Downloading $1 module for After Dark ..."
   meta=$(wget -qO- https://registry.npmjs.org/"$1"/latest)
   vers=$(echo "$meta" | grep -oE "\"version\".*[^,]*," | cut -d ',' -f1 | cut -d ':' -f2 | tr -d '" ')
   mkdir -p themes/"$1"
   wget -qO- https://registry.npmjs.org/"$1"/-/"$1"-"$vers".tgz | tar --strip-components=1 -xz -C themes/"$1"
   echo "Version $vers downloaded to $SITE_DIR/themes/$1"
}

configure_theme() {
   echo "Configuring basic After Dark theme settings ..."
   configfile=config.toml
   parse_hugo_vers
   [ "$(vers "$HUGO_VERSION")" -ge "$(vers "0.112")" ] && configfile=hugo.toml
   tee "${configfile}" >/dev/null <<TOML
baseurl = "https://domain.example" # Controls base URL sitewide
languageCode = "en-US" # Controls site language
title = "$SITE_NAME" # Homepage title and page title suffix
paginate = 11 # Number of posts to show before paginating
copyright = "Copyright &copy; Copyright Owner. Licensed under <a target=\"_blank\" rel=\"external license\" href=\"https://creativecommons.org/licenses/by-nd/4.0/\">CC BY-ND 4.0</a>." # Optional, remove to suppress copyright notices

# Controls default theme and theme components
theme = [
  "fractal-forest", # OBSD
  "after-dark" # AGPL-3.0-or-later
]

disableLiveReload = false # Optional, set true to disable live reload
enableRobotsTXT = true # Suggested, enable robots.txt file
sectionPagesMenu = "main" # Enable menu system for lazy bloggers

[markup.goldmark.renderer]
  unsafe = true # Optional, allows HTML inside your CommonMark content
[markup.tableOfContents]
  startLevel = 1 # Suggested, draws TOC using all heading levels
  endLevel = 6 # Suggested, draws TOC using all heading levels
[markup.highlight]
  noClasses = false # Suggested, used for custom syntax highlighting

[params]
  description = "" # Suggested, controls default description meta
  author = "" # Optional, controls author name display on posts
  hide_author = false # Optional, set true to hide author name on posts
  disable_csp = false # Optional, set true to disable content security policy
  images = [
    "https://source.unsplash.com/collection/983219/2000x1322"
  ] # Suggested, controls default Open Graph images

[params.layout.menu.main]
  hidden = true # Optional, set false or remove to show section menu

[params.layout.footer]
  hidden = false # Optional, set true to hide footer

[params.modules.fractal_forest]
  enabled = true # Optional, set false to disable module
  decoders = ["bpgdec8a"] # Optional, 8-bit javascript decoder with animation
TOML
}

update_archetypes() {
   echo "Updating the default content archetype ..."
   rm -f archetypes/default.md
   cp themes/after-dark/archetypes/default.md archetypes
}

create_welcome_post() {
   echo "Creating welcome post ..."
   hugo new post/welcome.md 1>/dev/null
}

serve_site() {
   echo "Starting site server ..."
   hugo serve --buildDrafts --navigateToChanged --port 1313 1>/dev/null &
}

generate_help_docs() {
   echo "Generating help documentation ..."
   THEME_PATH=themes/after-dark
   meta_path="$THEME_PATH"/data/npm
   mkdir -p "$meta_path" && echo "$LATEST_META" | tr '\r\n' ' ' >"$meta_path"/latest.json
   cd "$THEME_PATH"/docs && mkdir themes && ln -s ../.. "$THEME_PATH"
   hugo new validate.md --kind validate 1>/dev/null
}

serve_help() {
   echo "Starting help server ..."
   hugo serve --disableLiveReload --port 1414 1>/dev/null &
}

echo "Welcome to the After Dark quick installer. Press CTRL-C at any time to abort."

if [ -n "${AFTRDRK_INTERACTIVE_INSTALL-}" ]; then
   confirm_intent
fi
validate_hugo
if [ -n "${AFTRDRK_INTERACTIVE_INSTALL-}" ]; then
   prompt_site_name
   prompt_install_dir
else
   set_default_site_name
   set_default_install_dir
fi
create_site_dir
create_site
download_theme
update_archetypes
download_module "fractal-forest"
configure_theme
create_welcome_post
serve_site
generate_help_docs
serve_help

lime_yellow=$(tput setaf 190)
normal=$(tput sgr0)

printf '%sInstallation successful!%s\n' "${lime_yellow}" "${normal}"
echo "Site created in $SITE_DIR_ABS"
echo "Site server started at http://localhost:1313/"
echo "To stop it run \"kill \$(ps aux | awk '/[h]ugo.*1313/ {print \$2}')\"."
echo "Help server started at http://localhost:1414/"
echo "To stop and restart it run \"./themes/after-dark/bin/help\"."
echo "Thank you for choosing After Dark."
