#!/usr/bin/env bash
# Release automation script for token lists
# Handles version bumping, validation, and release preparation

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TOKEN_LISTS_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
LISTS_DIR="$TOKEN_LISTS_DIR/lists"
TOKEN_LIST_FILE="$LISTS_DIR/dbis-138.tokenlist.json"
CHANGELOG_FILE="$TOKEN_LISTS_DIR/docs/CHANGELOG.md"

# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[✓]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# Check if jq is available
if ! command -v jq &> /dev/null; then
    log_error "jq is required but not installed"
    exit 1
fi

# Check if node is available
if ! command -v node &> /dev/null; then
    log_error "node is required but not installed"
    exit 1
fi

# Get current version
get_current_version() {
    jq -r '.version | "\(.major).\(.minor).\(.patch)"' "$TOKEN_LIST_FILE"
}

# Bump version
bump_version() {
    local bump_type="${1:-patch}" # major, minor, patch
    local current_major current_minor current_patch
    
    current_major=$(jq -r '.version.major' "$TOKEN_LIST_FILE")
    current_minor=$(jq -r '.version.minor' "$TOKEN_LIST_FILE")
    current_patch=$(jq -r '.version.patch' "$TOKEN_LIST_FILE")
    
    case "$bump_type" in
        major)
            ((current_major++))
            current_minor=0
            current_patch=0
            ;;
        minor)
            ((current_minor++))
            current_patch=0
            ;;
        patch)
            ((current_patch++))
            ;;
        *)
            log_error "Invalid bump type: $bump_type (must be major, minor, or patch)"
            exit 1
            ;;
    esac
    
    # Update version in JSON
    local tmp_file=$(mktemp)
    jq --arg major "$current_major" --arg minor "$current_minor" --arg patch "$current_patch" \
       '.version.major = ($major | tonumber) | .version.minor = ($minor | tonumber) | .version.patch = ($patch | tonumber)' \
       "$TOKEN_LIST_FILE" > "$tmp_file"
    mv "$tmp_file" "$TOKEN_LIST_FILE"
    
    echo "$current_major.$current_minor.$current_patch"
}

# Update timestamp
update_timestamp() {
    local timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")
    local tmp_file=$(mktemp)
    jq --arg ts "$timestamp" '.timestamp = $ts' "$TOKEN_LIST_FILE" > "$tmp_file"
    mv "$tmp_file" "$TOKEN_LIST_FILE"
    log_success "Updated timestamp to: $timestamp"
}

# Run all validations
run_validations() {
    log_info "Running validations..."
    
    # JSON schema and basic validation
    log_info "Validating token list schema..."
    if ! node "$SCRIPT_DIR/validate-token-list.js" "$TOKEN_LIST_FILE"; then
        log_error "Schema validation failed"
        return 1
    fi
    
    # Checksum validation
    log_info "Validating address checksums..."
    if ! node "$SCRIPT_DIR/checksum-addresses.js" "$TOKEN_LIST_FILE"; then
        log_error "Checksum validation failed"
        return 1
    fi
    
    # Logo validation (non-blocking)
    log_info "Validating logos..."
    node "$SCRIPT_DIR/validate-logos.js" "$TOKEN_LIST_FILE" || log_warn "Logo validation had issues (continuing)"
    
    log_success "All critical validations passed"
    return 0
}

# Generate release notes from CHANGELOG
generate_release_notes() {
    local version="$1"
    
    if [[ ! -f "$CHANGELOG_FILE" ]]; then
        log_warn "CHANGELOG.md not found, skipping release notes generation"
        return
    fi
    
    # Extract section for this version
    log_info "Extracting release notes for version $version from CHANGELOG.md"
    # This is a simple implementation - you might want to use a more sophisticated parser
    if grep -q "## \[$version\]" "$CHANGELOG_FILE"; then
        log_success "Release notes found in CHANGELOG.md"
    else
        log_warn "No release notes found for version $version in CHANGELOG.md"
    fi
}

# Main release function
main() {
    local bump_type="${1:-patch}"
    local skip_validation="${2:-}"
    
    log_info "========================================="
    log_info "Token List Release Preparation"
    log_info "========================================="
    log_info ""
    
    # Check if file exists
    if [[ ! -f "$TOKEN_LIST_FILE" ]]; then
        log_error "Token list file not found: $TOKEN_LIST_FILE"
        exit 1
    fi
    
    local current_version=$(get_current_version)
    log_info "Current version: $current_version"
    
    # Bump version
    log_info "Bumping $bump_type version..."
    local new_version=$(bump_version "$bump_type")
    log_success "New version: $new_version"
    
    # Update timestamp
    update_timestamp
    
    # Run validations (unless skipped)
    if [[ -z "$skip_validation" ]]; then
        if ! run_validations; then
            log_error "Validation failed. Release aborted."
            log_info "You can fix the issues and run again, or use --skip-validation to bypass"
            exit 1
        fi
    else
        log_warn "Skipping validations (--skip-validation flag)"
    fi
    
    # Generate release notes
    generate_release_notes "$new_version"
    
    log_info ""
    log_success "Release preparation complete!"
    log_info ""
    log_info "Next steps:"
    log_info "1. Review changes: git diff $TOKEN_LIST_FILE"
    log_info "2. Commit: git add $TOKEN_LIST_FILE"
    log_info "3. Create tag: git tag -a v$new_version -m \"Release v$new_version\""
    log_info "4. Push: git push && git push --tags"
    log_info ""
    log_info "Or run the signing script: $SCRIPT_DIR/sign-list.sh"
}

# Parse arguments
if [[ "${1:-}" == "--help" ]] || [[ "${1:-}" == "-h" ]]; then
    echo "Usage: $0 [bump-type] [--skip-validation]"
    echo ""
    echo "Bump types: major, minor, patch (default: patch)"
    echo ""
    echo "Examples:"
    echo "  $0 patch              # Bump patch version"
    echo "  $0 minor              # Bump minor version"
    echo "  $0 major              # Bump major version"
    echo "  $0 patch --skip-validation  # Skip validation checks"
    exit 0
fi

main "${1:-patch}" "${2:-}"

