#!/usr/bin/bash
repos="/tmp/repos-$(cat /dev/urandom | base64 | tr -d '=+/' | head -c 8)"
if [ -d "$repos" ]; then
	echo "Error: Temporary directory '$repos' already exists."
	exit 1
fi
mkdir -p "$repos"
tmp_portfolio="/tmp/portfolio-$(cat /dev/urandom | base64 | tr -d '=+/' | head -c 8)"
if [ -d "$tmp_portfolio" ]; then
	echo "Error: Temporary directory '$tmp_portfolio' already exists."
	exit 1
fi
function safely_remove_tmp_repos() {
	if [ "$repos" ] && [ -d "$repos" ]; then
		if [ "$(find -name .git -type d | wc -l)" -eq 0 ]; then
			echo "Warning: No git repositories found in '$repos'. Not deleting to prevent data loss."
			rmdir "$repos" 2>/dev/null
			return
		fi
		rm -rf "$repos"
	fi
	rm -r "$tmp_portfolio"
}
function cleanup() {
	safely_remove_tmp_repos
}
trap cleanup EXIT
directory="$1"
script_dir="$(dirname "$0")"
if [ ! "$directory" ]; then
	echo "Usage: $0 <directory>"
	exit 1
fi
if ! command -v pass >/dev/null 2>&1; then
	echo "Error: 'pass' command not found. Please install 'pass' and set up your Gitea API token."
	exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
	echo "Error: 'jq' command not found. Please install 'jq' to process JSON data."
	exit 1
fi
if ! command -v Rscript >/dev/null 2>&1; then
	echo "Error: 'Rscript' command not found. Please install R to generate language distribution plots."
	exit 1
fi
if ! command -v quarto >/dev/null 2>&1; then
	echo "Error: 'quarto' command not found. Please install Quarto to render project pages."
	exit 1
fi
GIT_URL='https://git.seanhealy.ie'
GIT_USER=sean
GITHUB_USER=seanhly
GITLAB_USER=seanhly
CODEBERG_USER=seanhly
TOKEN="$(pass gitea-api-token)"
EXCLUDE_LANGUAGES=(Makefile TeX)
function my_curl() {
curl -s "$GIT_URL/api/v1/users/$GIT_USER/repos" \
	-H 'Accept: application/json' \
	-H "Authorization: $TOKEN" | jq -c '
		sort_by(.updated_at) | reverse | .[] | select(.private == false) | select(.empty == false) | [
			.name,
			 .description,
			 .languages_url,
			 .website,
			 .updated_at,
			 .avatar_url,
			 .licenses
		 ]'
}
mkdir -p "$tmp_portfolio"
portfolio_index=""
while read project; do
	i=0
	name=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	echo "Processing $name..."
	description=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	languages_url=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	languages="$(curl -s "$languages_url" -H "Authorization: $TOKEN" |
		jq -r 'to_entries[]|[.key,.value]|@tsv')"
	total_bytes=$(echo "$languages" | awk '{sum += $2} END {print sum}')
	languages_percentages=$(echo "$languages" |
		awk -v total="$total_bytes" '{print $2 / total"\t"$1}' |
		sort -n -r
	)
	git clone --depth 1 -b main --single-branch "$GIT_URL/$GIT_USER/$name" "$repos/$name" 2>/dev/null >/dev/null
	echo $'Percentage\tLanguages' > /tmp/languages.tsv
	echo "$languages_percentages" >> /tmp/languages.tsv
	(cat > /tmp/plot.R) <<EOF
	#!/usr/bin/Rscript
	library(ggplot2)
	data <- read.csv("/tmp/languages.tsv", sep="\t")
	data\$Languages <- factor(data\$Languages, levels=data\$Languages[order(data\$Percentage, decreasing=TRUE)])
	if (nrow(data) == 1) {
		data\$Percentage <- 0
	}
	plot <- ggplot(data, aes(x="", y=Percentage, fill=Languages)) +
		geom_bar(stat="identity", width=1) +
		coord_polar("y", start=0) +
		theme_void() +
		scale_fill_brewer(palette="Set3") +
		theme(legend.text=element_text(size=16), legend.title=element_text(size=18))
	ggsave("$repos/$name/$name-languages.png", plot, width=5, height=5)
EOF
	Rscript /tmp/plot.R
	language_list="$(
		(cut -d$'\t' -f2 <<< "$languages_percentages") |
			grep -v -F -w -f <(printf "%s\n" "${EXCLUDE_LANGUAGES[@]}")
	)"
	website=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	updated_at=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	updated_at=$(date -d "$updated_at" +"%B %d, %Y")
	avatar_url=$(jq -r ".[$i]" <<< "$project"); i=$((i + 1))
	licenses=$(jq -r '.['$i'] | join(", ")' <<< "$project"); i=$((i + 1))
	cp "$script_dir/project-style.css" "$repos/$name/"
	(cd "$repos/$name" && (cat > "$name.qmd") <<EOF
---
execute:
  enabled: false
format:
  html:
    embed-resources: true
    css: project-style.css
---

[← Back to Portfolio](index.html)

Mirrors:

- [codeberg.org/$CODEBERG_USER/$name](https://codeberg.org/$CODEBERG_USER/$name)
- [github.com/$GITHUB_USER/$name](https://github.com/$GITHUB_USER/$name)
- [gitlab.com/$GITLAB_USER/$name](https://gitlab.com/$GITLAB_USER/$name)

![Languages used](./$name-languages.png)

\`\`\`{bash}
git clone https://codeberg.org/$CODEBERG_USER/$name
\`\`\`

$(cat README.md)
EOF
	)
	portfolio_index+="$(
		cat <<EOF
			<a href="$name.html">
			<section>
				<h2>$name</h2>
				<img src="$avatar_url" alt="Avatar" width="100" height="100" alt="$name (logo)">
				<p>$description</p>
				<ul class="languages">
EOF
	)"
	(cd "$repos/$name" &&
		quarto render "$name.qmd" -o "$name.html" >/dev/null 2>/dev/null &&
		mv "$name.html" "$tmp_portfolio/$name.html"
	)
	while read -r language; do
		portfolio_index+="<li class='language'>$language</li>"
	done <<< "$language_list"
	portfolio_index+="$(
		cat <<EOF
			</ul>
			<p>Last Updated: $updated_at</p>
			<p>Licenses: $licenses</p>
		</section>
		</a>
EOF
	)"
done < <(my_curl)
portfolio_index="$(
cat <<EOF
<!DOCTYPE html>
<html>
<head>
<title>Projects</title>
<body>
<h1>Projects</h1>
<div id="git-portfolio">
<style>
#git-portfolio {
	display: inline-flex;
	flex-wrap: wrap;
}
#git-portfolio section {
	padding: 15px;
	margin: 10px;
	border-radius: 20px;
	background: linear-gradient(30deg, rgba(100, 43, 200, 0.4), rgba(198, 66, 110, 0.4));
	position: relative;
	width: calc(100% - 25px);
	box-sizing: border-box;
	max-width: 420px;
}
#git-portfolio a {
	color: black;
	text-decoration: none;
	display: inline-flex;
	flex-direction: column;
	flex-grow: 1;
	min-width: 400px;
	max-width: 450px;
	box-sizing: content-box;
}
#git-portfolio section ul.languages {
	float: right;
	position: absolute;
	right: 15px;
	top: 0;
}
#git-portfolio h2 {
  font-family: "Courier New", monospace;
}
li.language {
	display: inline-block;
	background: lightgray;
	padding: 5px 10px;
	border-radius: 20px;
	margin: 5px;
}
</style>
	$portfolio_index
</div>
EOF
)"
echo "$portfolio_index" > "$tmp_portfolio/index.html"
if [ -d "$directory" ]; then
	if [ "$(du -sb "$directory" | cut -f1)" -gt $((1024 * 1024 * 400)) ]; then
		echo "Error: Directory '$directory' contains more than 400MB of data.  Exiting to prevent data loss."
		exit 1
	fi
else
	mkdir -p "$directory"
fi
rsync -a "$tmp_portfolio/" "$directory/"
