#!/bin/env zsh

# License: GPL v2.0 and newer

# Script to generate static html files from input
# Includes
# - Header
# - Body
# - Footer

VERSION="0.6.2" # Sun-2024-01-21
root_dir=${HOME}/www/text
OUTPUT=${HOME}/www_root/blog.kekepower.com
HEADER=${root_dir}/site/header.tpl
FOOTER=${root_dir}/site/footer.tpl
BLOG_TPL=${root_dir}/site/blog.tpl
BLOG_IDX_TPL=${root_dir}/site/blog_index.tpl
TODAY=$( date "+%Y-%m-%d - %T" )
BLOGDATE=$( date +%a-%Y-%b-%d )

# Define cache files
blog_cache_file="${root_dir}/.blog_cache"
pages_cache_file="${root_dir}/.pages_cache"

# Set to true or false
# This will show debug information from almost every function in this script
debug=false

if [[ ${1} == "help" ]]; then
	echo "This is where I'll write the Help documentation."
	exit
fi

function include () {

        # Edit this path to reflect your installation
        local inc_file
        inc_file=${HOME}/bin/include/${1}.inc
        if [[ ! -f ${inc_file} ]]; then
                local inc_opt
                inc_opt=$( echo ${1} | cut -d\/ -f2 )
                echo "Supplied option \"${inc_opt}\" is not valid."
                echo "Not critical. Will continue and use the default \"--with=clean,addons\"."
        else
                builtin source ${inc_file} ${2}
        fi

}

include common/colors

echo "${white}Running ${0:t} ${VERSION}${end}"

builtin cd ${root_dir}

# Let's create arrays of all the files we'll be working on
# This will hopefully speed up the script a little

ls -har blog/*idx | while read -r file; do
blog_idx_array+=($file)
done
ls -1btar blog/*blog | while read -r file; do
blog_index_file_array+=($file)
done

# BLOG CACHE

# Create an associative array for the blog cache
typeset -A blog_cache

# Load the existing blog cache
if [[ -f $blog_cache_file ]]; then
    while IFS=':' read -r name hash; do
        blog_cache[$name]=$hash
		if (${debug}) echo "HASH VALUE: ${blog_cache[${name}]}"
    done < "$blog_cache_file"
fi

# Initialize the array for storing blog files to process
make_blog_array=()

# Process blog files
for blog_file in $(ls -har blog/*.blog); do
    # Compute the current blog file hash
    current_hash=$(md5sum "$blog_file" | awk '{print $1}')

	if (${debug}) echo "1. blog_cache: ${blog_cache[$blog_file]}"
	if (${debug}) echo "1. current_cache: ${current_hash}"

    # Check if the blog file is new or has changed
    if [[ ${blog_cache[$blog_file]} != "$current_hash" ]]; then
		if (${debug}) echo "2. cache_file: ${blog_cache[$blog_file]}"
		if (${debug}) echo "2. current_cache: ${current_hash}"
        # Blog file is new or has changed; add it to the processing array
        make_blog_array+=("$blog_file")

        # Update the blog cache with the new hash
        blog_cache[$blog_file]=$current_hash
    fi
done

# Rebuild the blog cache file from scratch
: >| "$blog_cache_file"  # Truncate the file before writing
for name in "${(@k)blog_cache}"; do
    echo "$name:${blog_cache[$name]}" >> "$blog_cache_file"
done



# PAGES CACHE

# Create an associative array for the pages cache
typeset -A pages_cache

# Load the existing pages cache
if [[ -f $pages_cache_file ]]; then
    while IFS=':' read -r name hash; do
        pages_cache[$name]=$hash
		if (${debug}) echo "PAGES HASH VALUE: ${pages_cache[${name}]}"
    done < "$pages_cache_file"
fi

# Initialize the array for storing pages files to process
tpl_array=()

# Process pages files
for file in $(ls -1bt *tpl); do
    # Compute the current blog file hash
    current_hash=$(md5sum "$file" | awk '{print $1}')

	if (${debug}) echo "1. pages_cache: ${pages_cache[$file]}"
	if (${debug}) echo "1. current_cache: ${current_hash}"

    # Check if the pages file is new or has changed
    if [[ ${pages_cache[$file]} != "$current_hash" ]]; then
		if (${debug}) echo "2. pages_file: ${pages_cache[$file]}"
		if (${debug}) echo "2. current_cache: ${current_hash}"
        # Pages file is new or has changed; add it to the processing array
        tpl_array+=("$file")

        # Update the pages cache with the new hash
        pages_cache[$file]=$current_hash
    fi
done

# Rebuild the pages cache file from scratch
: >| "$pages_cache_file"  # Truncate the file before writing
for name in "${(@k)pages_cache}"; do
    echo "$name:${pages_cache[$name]}" >> "$pages_cache_file"
done

# End of arrays

function header() {

	if [[ $( grep title ${1} | head -2) ]]; then
		title=$( cat ${1} | head -2 | grep '#title' | cut -d= -f2 )
		NEW_HEADER=$( cat ${HEADER} | sed -e "s|#pagetitle|${title}|" )
	else
		NEW_HEADER=$( cat ${HEADER} | sed -e "s|#pagetitle|No\ title\ supplied|" )
	fi
	echo ${NEW_HEADER} > ${OUTPUT}/${1%.*}.html

}

function footer() {

	NEW_FOOTER=$( cat ${FOOTER} | sed -e "s|#updated|${TODAY}|" | sed -e "s|#version|${VERSION}|" )
	echo ${NEW_FOOTER} >> ${OUTPUT}/${1%.*}.html

}

function genlink() {

	local TMP_OUTPUT
    local debug=false

    # Process the file line by line
    while IFS= read -r line; do
        if [[ $line == *"#link"* ]]; then
            if (${debug}) echo "URL_MAIN: (${1}) $line"

            # Extract the URL and the link text
            local url_full=$(echo "$line" | awk -F'#link ' '{print $2}' | awk -F'¤' '{print $1 "¤" $2}')
            local url_dest=$(echo "$url_full" | awk -F'¤' '{print $1}')
            local url_txt=$(echo "$url_full" | awk -F'¤' '{print $2}')

            if (${debug}) echo "URL: $url_dest"
            if (${debug}) echo "Text: $url_txt"

            # Form the replacement HTML link
            local modified_link="<a href=\"$url_dest\">$url_txt"
            if [[ $url_dest =~ ^https?:// ]]; then
                # Add external link icon for external URLs
                modified_link+="<img class=\"exticon\" alt=\"External site icon\" src=\"/images/ext-url.png\" width=\"16\" />"
            fi
            modified_link+="</a>"
            line=${line//"#link $url_full"/$modified_link}
        fi
		# TMP_OUTPUT="${line}"
        echo "$line" >> "${OUTPUT}/${1%.*}.tmp.html"
    done < "${OUTPUT}/${1%.*}.html"

    # Replace the original file with the modified one
    mv "${OUTPUT}/${1%.*}.tmp.html" "${OUTPUT}/${1%.*}.html"
	# echo "${TMP_OUTPUT}" > "${OUTPUT}/${1%.*}.html"
}

function img() {

	local get_img img_link image img_alt
	local debug=false

	cat ${OUTPUT}/${1%.*}.html | sed "s/\.\ /\.\\n/g" | sed "s/\,/\,\\n/g" | sed "s/\#/\\n\#/g" | grep -P '(?=.*?#showimg)' |\
		while read img
		do
		if [[ ${img} != "" ]]; then
			get_img=$( echo "${img}" | awk '/#showimg/' | cut -d# -f2- )
			if (${debug}) echo "GET_IMG: $get_img"
			img_link=$( echo ${get_img} | cut -d' ' -f2- )
			if (${debug}) echo "IMG_LINK: $img_link"
			image=$( echo ${img_link} | cut -d¤ -f1 | cut -d¤ -f1- )
			if (${debug}) echo "IMAGE: $image"
			if [[ ${image} =~ ^https* ]]; then
				real_image=${image}
				if (${debug}) echo "HTTPS REAL_IMAGE: ${real_image}"
			elif [[ ${image} =~ ^\/ ]]; then
				# This is for images in another directory and the image link begins with a /
				real_image=${image}
				if (${debug}) echo "SLASH REAL_IMAGE: ${real_image}"
			else
				real_image="/images/${image}"
				if (${debug}) echo "IMAGES REAL_IMAGE: ${real_image}"
			fi
			if (${debug}) echo "REAL_IMAGE: $real_image"
			img_alt=$( echo ${img_link} | cut -d¤ -f2- | cut -d¤ -f1- )
			if (${debug}) echo "IMG_ALT: $img_alt"
			echo ${img_link} |\
				sed -i -- "s|${image}|<img src=\"${real_image}\"|" ${OUTPUT}/${1%.*}.html
				sed -i -- 's|'${img_alt}'| alt=\"'${img_alt}'\" width=\"500\" \/>|' ${OUTPUT}/${1%.*}.html
		fi
		done
}

function yt_video() {

	local yt_id
	local debug=false

	if (${debug}) echo "${red}Creating YouTube player embed${end}"

	cat ${OUTPUT}/${1%.*}.html | sed "s/\.\ /\.\\n/g" | sed "s/\,/\,\\n/g" | sed "s/\#/\\n\#/g" | grep -P '(?=.*?#ytvideo)' |\
		while read video
		do
		if [[ ${video} != "" ]]; then
			yt_id=$( echo "${video}" | awk '/#ytvideo/' | cut -d" " -f2 )
			if (${debug}) echo "YT VIDEO ID: ${yt_id}"
			sed -i -- "s|${yt_id}|<iframe width=\"560\" height=\"315\" src=\"https:\/\/www.youtube.com\/embed\/${yt_id}\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen><\/iframe>|" ${OUTPUT}/${1%.*}.html
		fi
		done

}

function clean_url() {

	local debug=false

	if (${debug}) echo "${red}Cleaning up links in: ${OUTPUT}/${1%.*}.html${end}"
	sed -i -- "s|¤||g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|#showimg\ ||g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|#ytvideo\ ||g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|#link\ ||g" ${OUTPUT}/${1%.*}.html

}

function html() {

	sed -i -- "s|\#BR|<br\ />\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#U|<u>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EU|</u>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#P|<p>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EP|</p>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#Q|<blockquote>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EQ|</blockquote>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#STRONG|<strong>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#ESTRONG|</strong>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#I|<i>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EI|</i>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#C|<code>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EC|</code>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EM|<em>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#SEM|</em>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#OT|\&quot;|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#UL|<ul>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#OL|<ol>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#LI|<li class=\"libody\">|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#ELI|</li>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EUL|</ul>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EOL|</ol>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H1|<h1>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H2|<h2>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H3|<h3>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H4|<h4>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H5|<h5>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#H6|<h6>|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH1|</h1>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH2|</h2>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH3|</h3>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH4|</h4>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH5|</h5>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#EH6|</h6>\n|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#LT|\&lt;|g" ${OUTPUT}/${1%.*}.html
	sed -i -- "s|\#GT|\&gt;|g" ${OUTPUT}/${1%.*}.html

}

function make_blog() {

	local sdate btitle ingress body blog_index blog_dir blog_url
	local debug=false
	export break_blog=false

	for blog in ${make_blog_array[@]}
		do
		if ($debug) echo "MAKE_BLOG: Processing ${blog}"

        # Read the file once
        local content="$(<${blog})"

		sed -i "s/GETDATE/${BLOGDATE}/" ${blog}
        # Array sdate = Name day=4, Year=2, Month=3, Number day=1
        sdate=( $( echo ${content} | grep DATE | sed "s|DATE\ ||" | sed "s|\-|\ |g" ) )
        btitle=$( echo ${content} | grep BLOG_TITLE | cut -d' ' -f2- )
        ingress=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#INGRESS_START\K(.*?)#INGRESS_STOP" | sed "s|\ \#INGRESS_STOP||" | sed "s|^\ ||" )
        body=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#BODY_START\K(.*?)#BODY_STOP" | sed "s|\ \#BODY_STOP||" | sed "s|^\ ||" )
        blog_index=$( echo ${btitle} | sed -e "s|-|_|" | sed -e "s|\ |-|g" | sed -e "s|\,||g" | sed -e "s|\.||" )
        blog_dir="/blog/${sdate[2]}/${sdate[3]}/${sdate[4]}"
        blog_url="${blog_dir}/${blog_index}.html"

				if [[ ! -d ${OUTPUT}${blog_dir} ]]; then
					if (${debug}) echo "Creating blog directory: ${OUTPUT}${blog_dir}"
					mkdir -p ${OUTPUT}${blog_dir}
				fi

				if (${debug}) echo "BLOG_IDX_TPL: ${BLOG_IDX_TPL}"
				tee < ${BLOG_IDX_TPL} | sed					\
                    -e "s|BLOGTITLE|${btitle}|"				\
                    -e "s|CALADAY|${sdate[1]}|"				\
                    -e "s|CALNDAY|${sdate[4]}|"				\
                    -e "s|CALMONTH|${sdate[3]}|"			\
                    -e "s|CALYEAR|${sdate[2]}|"				\
                    -e "s|BLOGURL|${blog_url}|"				\
                    -e "s|INGRESS|${ingress}|"				\
                    -e "s|DATE ||"							\
                    > ${blog%.*}.idx

				if [[ ! $( cat ${blog%.*}.idx | grep "#title" ) ]]; then
					NEW_HEADER=$( cat ${HEADER} | sed -e "s|#pagetitle|${btitle}|" )
				else
					NEW_HEADER=$( cat ${HEADER} | sed -e "s|#pagetitle|Blog|" )
				fi
				echo ${NEW_HEADER} > ${OUTPUT}${blog_url}

				if (${debug}) echo "BLOG_URL_TPL: ${OUTPUT}${blog_url}"
				tee < ${BLOG_TPL} | sed 			\
					-e "s|BLOGTITLE|${btitle}|"		\
					-e "s|CALADAY|${sdate[1]}|"		\
					-e "s|CALNDAY|${sdate[4]}|"		\
					-e "s|CALMONTH|${sdate[3]}|"	\
					-e "s|CALYEAR|${sdate[2]}|"		\
					-e "s|INGRESS|${ingress}|"		\
					-e "s|BODY|${body}|"			\
					-e "s|DATE ||"					\
					-e "s|\#title||"				\
					>> ${OUTPUT}${blog_url}

				NEW_FOOTER=$( tee < ${FOOTER} | sed -e "s|#updated|${TODAY}|" | sed -e "s|\#version|${VERSION}|" )
				if (${debug}) echo "Generating: footer for ${blog_url}"
				echo ${NEW_FOOTER} >> ${OUTPUT}${blog_url}
				img ${blog_url}
				html ${blog_url}
				genlink ${blog_url}
				yt_video ${blog_url}
				clean_url ${blog_url}

		done

}

function blog_index() {

	###########################################################################################################
	# This function creates the list of blog links, titles and ingresses on the main index page (/index.html) #
	###########################################################################################################

	if (( ${#make_blog_array[@]} > 0 )) || (( ${#tpl_array[@]} > 0 )); then

	local debug=false

	echo "${green}Generating blog entries for index.html${end}"
	if (${debug}) echo "${red}BLOG: ${make_blog_array[@]}${end}"

	if (${debug}) echo "${red}Generating blog indexes and blogs${end}"

	# make_blog creates all the blog files that resides in /blog/
	make_blog

	if (${debug}) echo "Break Blog = ${break_blog}"
	if (${debug}) echo "Second step in blog index and pages"

		# Here we do the magic where all the links are added to the main page.
		if (${debug}) echo "${red}Inserting ${make_blog_array[@]} to index.html${end}"
		# echo "${OUTPUT}/index.html"
		for blogs in ${blog_idx_array[@]}
		do
			if (${debug}) echo "${red}BLOGS: ${blogs}${end}"
			tee < ${blogs} >> ${OUTPUT}/index.html
		done
		html ${1}
		img ${1}
		genlink ${1}
	else
		echo "${yellow}No new or updated blog posts detected.${end}"
	fi

}

function body() {

	html ${1}
	img ${1}
	genlink ${1}
	yt_video ${1}
	tee < ${1} | grep -v "#title=" >> ${OUTPUT}/${1%.*}.html

}

function generate_pages() {
	echo "${green}Generating Pages: ${1%.*}.html${end}"
	header ${1}
	body ${1}
	html ${1}
	img ${1}
	genlink ${1}
	yt_video ${1}
	clean_url ${1}
}

function gen_footer() {

	local debug=false

	echo "${green}Generating footers${end}"

	for t in ${tpl_array[@]}
	do
	       if (${debug}) echo "${red}- Generating Page: footer for ${t%.*}.html${end}"
	       footer ${t}
	done

}

if [[ ! ${1} ]]; then

	local debug=false

	if [[ ${tpl_array[@]} ]]; then
		for t in ${tpl_array[@]}
		do
			generate_pages ${t}
		done
		blog_index index.idx
		footer ${1}
	else
		echo "${yellow}No new or updated Pages detected.${end}"
	fi

	blog_index index.idx

	if (( ${#make_blog_array[@]} > 0 )) || (( ${#tpl_array[@]} > 0 )); then
		gen_footer
	fi

elif [[ ${tpl_array[@]} ]]; then
		if (${debug}) echo "Generating Pages including Blogs and Footer"
		generate_pages ${1}
		blog_index index.idx
		footer ${1}
else
	echo "${yellow}No new Pages detected.${end}"
fi