#!/bin/bash

### PURPOSE
# This script will automate pushing a PR branch into the docs.linea.build repo
# The new PR branch will contain autogenerated smart contract documentation for the Linea monorepo
# You must manually create the Github PR yourself (from the new branch)

### ASSUMPTIONS
# - Requires permissions to create a branch on docs.linea.build repo
# - Must execute this script from within linea-monorepo (can be anywhere)
# - Hardhat must be installed in the local project, Foundry must be installed globally

### CONSTANTS
DOCS_WEBSITE_REPO_NAME=doc.linea
DOCS_WEBSITE_REPO_GIT_LINK=https://github.com/Consensys/$DOCS_WEBSITE_REPO_NAME.git
DOCS_REPO_PR_BRANCH_NAME=update-linea-smart-contract-docs
DOCS_REPO_PR_COMMIT_MESSAGE="Update Linea smart contract docs"

UPDATE_SIDEBAR_SCRIPT_NAME=updateSidebar.js
UPDATE_SIDEBAR_SCRIPT_PATH=contracts/docs/scripts/$UPDATE_SIDEBAR_SCRIPT_NAME
MONOREPO_SMART_CONTRACT_DOCS_DIRECTORY=contracts/docs/api

DOCS_REPO_SMART_CONTRACT_DOC_DIRECTORY=docs/api/linea-smart-contracts

MAX_FOLDER_DEPTH=3

### SCRIPT START

# Ensure that `contracts` is the starting working directory
MONOREPO_ROOT_PATH=$(git rev-parse --show-toplevel)
cd $MONOREPO_ROOT_PATH
cd contracts

# Check required installations
if ! command -v forge &> /dev/null; then
    echo "Please install Foundry - https://book.getfoundry.sh/getting-started/installation"
    exit 1
fi

if ! command -v pnpm &> /dev/null; then
    echo "Please install pnpm - https://pnpm.io/installation"
    exit 1
fi

if [ -z "$(pnpm -F contracts list hardhat)" ]; then
    echo "Please install Hardhat - \`pnpm i\`"
    exit 1
fi

# Docgen
npx hardhat docgen

# Git clone docs website repo and create a new branch
cd $MONOREPO_ROOT_PATH
cd ..
git clone $DOCS_WEBSITE_REPO_GIT_LINK --depth 1
cd $DOCS_WEBSITE_REPO_NAME
DOCS_WEBSITE_REPO_PATH=$(pwd)
git checkout -b $DOCS_REPO_PR_BRANCH_NAME

# Copy autogenerated smart contract docs + UPDATE_SIDEBAR_SCRIPT to docs website repo
cd $MONOREPO_ROOT_PATH
rm -rf "$DOCS_WEBSITE_REPO_PATH/$DOCS_REPO_SMART_CONTRACT_DOC_DIRECTORY"
cp -r "$MONOREPO_ROOT_PATH/$MONOREPO_SMART_CONTRACT_DOCS_DIRECTORY" "$DOCS_WEBSITE_REPO_PATH/$DOCS_REPO_SMART_CONTRACT_DOC_DIRECTORY"
cp "$MONOREPO_ROOT_PATH/$UPDATE_SIDEBAR_SCRIPT_PATH" "$DOCS_WEBSITE_REPO_PATH/$UPDATE_SIDEBAR_SCRIPT_NAME"

# Ensure directories is entirely lowercase
# To pass Github Action enforcing no uppercase for file name
cd $DOCS_WEBSITE_REPO_PATH

# Purpose: Change folder names to lowercase
# Parameters:
#   $1 - max folder depth
function directory_to_lowercase_at_depth() {
    local DEPTH=$1
    for FOLDER in `find -d "$DOCS_REPO_SMART_CONTRACT_DOC_DIRECTORY" -type d -maxdepth $DEPTH`
    do
        NEW_FOLDER=$(echo $FOLDER | tr 'A-Z' 'a-z')
        if [[ "$FOLDER" != "$NEW_FOLDER" ]]; then
            mv $FOLDER $NEW_FOLDER
        fi
    done;
}

# Clumsy way of forcing `find` to do breadth-first search (BFS)
# Not a true BFS currently - as we 'descend' we are redundantly repeating BFS of previously explored folder depths
# Can tolerate inefficient implementation for readability
#
# The issue with default depth-first search (DFS) algorithm of `find` is that we mutate the folder list as iterate through it
# So the `mv` command spits errors because it is acting on stale folder names
# Seems that `find` first obtains the complete folder list, then iterates through the list to apply our for-loop
# What we want is for `find` to apply our for-loop body as it adds each item to the folder list
for ((i = 1; i <= MAX_FOLDER_DEPTH; i++)); do
  directory_to_lowercase_at_depth $i
done

# Ensure filenames is entirely lowercase
# To pass Github Action enforcing no uppercase for file name
for FILENAME in `find "$DOCS_REPO_SMART_CONTRACT_DOC_DIRECTORY" -type f  \( -iname \*.md -o -iname \*.mdx \)`
do
    NEW_FILENAME=$(echo $FILENAME | tr 'A-Z' 'a-z')
    mv $FILENAME $NEW_FILENAME
done;

# Execute UPDATE_SIDEBAR_SCRIPT then delete the script (so it is not in the commit)
cd $DOCS_WEBSITE_REPO_PATH
node $UPDATE_SIDEBAR_SCRIPT_NAME
rm $UPDATE_SIDEBAR_SCRIPT_NAME

# Git commit and push
git add .
git commit -m "$DOCS_REPO_PR_COMMIT_MESSAGE"
git push --set-upstream origin $DOCS_REPO_PR_BRANCH_NAME