#!/bin/bash
#
# Generate license files for all platform/arch combinations.
# This script handles architecture-specific dependency differences by:
# 1. Generating separate license reports per GOOS/GOARCH combination
# 2. Grouping identical reports together (comma-separated arch names)
# 3. Creating an index at the top of each platform file
# 4. Copying all license files to third-party/
#
# Note: third-party/ is a union of all license files across all architectures.
# This means that license files for dependencies present in only some architectures
# may still appear in third-party/. This is intentional and ensures compliance.
#
# Note: we ignore warnings because we want the command to succeed, however the output should be checked
#       for any new warnings, and potentially we may need to add license information.
#
#       Normally these warnings are packages containing non go code, which may or may not require explicit attribution,
#       depending on the license.
set -e

# Pinned version for reproducibility
# See: https://github.com/cli/cli/pull/11161
go install github.com/google/go-licenses/v2@v2.0.1

# actions/setup-go does not setup the installed toolchain to be preferred over the system install,
# which causes go-licenses to raise "Package ... does not have module info" errors in CI.
# For more information, https://github.com/google/go-licenses/issues/244#issuecomment-1885098633
if [ "$CI" = "true" ]; then
    export GOROOT=$(go env GOROOT)
    export PATH=${GOROOT}/bin:$PATH
fi

# actions/setup-go does not setup the installed toolchain to be preferred over the system install,
# which causes go-licenses to raise "Package ... does not have module info" errors in CI.
# For more information, https://github.com/google/go-licenses/issues/244#issuecomment-1885098633
if [ "$CI" = "true" ]; then
    export GOROOT=$(go env GOROOT)
    export PATH=${GOROOT}/bin:$PATH
fi

rm -rf third-party
mkdir -p third-party
export TEMPDIR="$(mktemp -d)"

trap "rm -fr ${TEMPDIR}" EXIT

# Cross-platform hash function (works on both Linux and macOS)
compute_hash() {
    if command -v md5sum >/dev/null 2>&1; then
        md5sum | cut -d' ' -f1
    elif command -v md5 >/dev/null 2>&1; then
        md5 -q
    else
        # Fallback to cksum if neither is available
        cksum | cut -d' ' -f1
    fi
}

# Function to get architectures for a given OS
get_archs() {
    case "$1" in
        linux)   echo "386 amd64 arm64" ;;
        darwin)  echo "amd64 arm64" ;;
        windows) echo "386 amd64 arm64" ;;
    esac
}

# Generate reports for each platform/arch combination
for goos in darwin linux windows; do
    echo "Processing ${goos}..."
    
    archs=$(get_archs "$goos")
    
    for goarch in $archs; do
        echo "  Generating for ${goos}/${goarch}..."
        
        # Generate the license report for this arch
        report_file="${TEMPDIR}/${goos}_${goarch}_report.md"
        GOOS="${goos}" GOARCH="${goarch}" GOFLAGS=-mod=mod go-licenses report ./... --template .github/licenses.tmpl > "${report_file}" 2>/dev/null || echo "  (warnings ignored for ${goos}/${goarch})"
        
        # Save licenses to temp directory
        GOOS="${goos}" GOARCH="${goarch}" GOFLAGS=-mod=mod go-licenses save ./... --save_path="${TEMPDIR}/${goos}_${goarch}" --force 2>/dev/null || echo "  (warnings ignored for ${goos}/${goarch})"
        
        # Copy to third-party (accumulate all - union of all architectures for compliance)
        if [ -d "${TEMPDIR}/${goos}_${goarch}" ]; then
            cp -fR "${TEMPDIR}/${goos}_${goarch}"/* third-party/ 2>/dev/null || true
        fi
        
        # Extract just the package list (skip header), sort it, and hash it
        # Use LC_ALL=C for consistent sorting across different systems
        packages_file="${TEMPDIR}/${goos}_${goarch}_packages.txt"
        if [ -s "${report_file}" ] && grep -qE '^ - \[' "${report_file}" 2>/dev/null; then
            grep -E '^ - \[' "${report_file}" | LC_ALL=C sort > "${packages_file}"
            hash=$(cat "${packages_file}" | compute_hash)
        else
            echo "(FAILED TO GENERATE LICENSE REPORT FOR ${goos}/${goarch})" > "${packages_file}"
            hash="FAILED_${goos}_${goarch}"
        fi
        
        # Store hash for grouping
        echo "${hash}" > "${TEMPDIR}/${goos}_${goarch}_hash.txt"
    done
    
    # Group architectures with identical reports (deterministic order)
    # Create groups file: hash -> comma-separated archs
    groups_file="${TEMPDIR}/${goos}_groups.txt"
    rm -f "${groups_file}"
    
    # Process architectures in order to build groups
    for goarch in $archs; do
        hash=$(cat "${TEMPDIR}/${goos}_${goarch}_hash.txt")
        # Check if we've seen this hash before
        if grep -q "^${hash}:" "${groups_file}" 2>/dev/null; then
            # Append to existing group
            existing=$(grep "^${hash}:" "${groups_file}" | cut -d: -f2)
            sed -i.bak "s/^${hash}:.*/${hash}:${existing}, ${goarch}/" "${groups_file}"
            rm -f "${groups_file}.bak"
        else
            # New group
            echo "${hash}:${goarch}" >> "${groups_file}"
        fi
    done
    
    # Generate the combined report for this platform
    output_file="third-party-licenses.${goos}.md"
    
    cat > "${output_file}" << 'EOF'
# GitHub MCP Server dependencies

The following open source dependencies are used to build the [github/github-mcp-server][] GitHub Model Context Protocol Server.

## Table of Contents

EOF

    # Build table of contents (sorted for determinism)
    # Use LC_ALL=C for consistent sorting across different systems
    LC_ALL=C sort "${groups_file}" | while IFS=: read -r hash group_archs; do
        # Create anchor-friendly name
        anchor=$(echo "${group_archs}" | tr ', ' '-' | tr -s '-')
        echo "- [${group_archs}](#${anchor})" >> "${output_file}"
    done
    
    echo "" >> "${output_file}"
    echo "---" >> "${output_file}"
    echo "" >> "${output_file}"
    
    # Add each unique report section (sorted for determinism)
    # Use LC_ALL=C for consistent sorting across different systems
    LC_ALL=C sort "${groups_file}" | while IFS=: read -r hash group_archs; do
        # Get the packages from the first arch in this group
        first_arch=$(echo "${group_archs}" | cut -d',' -f1 | tr -d ' ')
        packages=$(cat "${TEMPDIR}/${goos}_${first_arch}_packages.txt")
        
        cat >> "${output_file}" << EOF
## ${group_archs}

The following packages are included for the ${group_archs} architectures.

${packages}

EOF
    done
    
    # Add footer
    echo "[github/github-mcp-server]: https://github.com/github/github-mcp-server" >> "${output_file}"
    
    echo "Generated ${output_file}"
done

echo "Done! License files generated."

