#!/bin/bash
set -e

echo "🚀 Building JavaScript client with OpenAPI generation and packaging..."

# Define paths
CLIENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${CLIENT_DIR}/../.." && pwd)"
DIST_DIR="${ROOT_DIR}/dist/clients/js"

# Ensure dist directory exists
mkdir -p "${DIST_DIR}"

echo "📂 Project structure:"
echo "  Root: ${ROOT_DIR}"
echo "  Client: ${CLIENT_DIR}"
echo "  Output: ${DIST_DIR}"

# Step 1: Extract OpenAPI spec from server build
echo ""
echo "🔧 Step 1: Building server and extracting OpenAPI specification..."
cd "${ROOT_DIR}"

# Build server to extract OpenAPI spec
if ! ./gradlew :server:build -x test; then
    echo "❌ Server build failed. Cannot extract OpenAPI spec."
    exit 1
fi

# Create API directory and copy OpenAPI spec
mkdir -p "${CLIENT_DIR}/api"
server_spec="${ROOT_DIR}/server/build/classes/java/main/openapi-plugin/openapi-default.json"

if [ -f "$server_spec" ]; then
    cp "$server_spec" "${CLIENT_DIR}/api/openapi.json"
    echo "✅ OpenAPI spec extracted to: ${CLIENT_DIR}/api/openapi.json"
else
    echo "❌ OpenAPI spec not found at: $server_spec"
    exit 1
fi

# Step 2: Generate JavaScript client using OpenAPI Generator
echo ""
echo "🔧 Step 2: Generating JavaScript client from OpenAPI specification..."
cd "${CLIENT_DIR}"

# Backup package.json if it exists (to preserve any CI updates)
if [ -f "package.json" ]; then
    echo "📦 Backing up existing package.json..."
    cp package.json package.json.backup
fi

# Use OpenAPI Generator to generate JavaScript client
echo "🔄 Running OpenAPI Generator..."
docker run --rm \
  -v ${PWD}:/local \
  openapitools/openapi-generator-cli:latest generate \
  -i /local/api/openapi.json \
  -g javascript \
  -o /local \
  --package-name "@pairsystems/goodmem-client" \
  --git-user-id PAIR-Systems-Inc \
  --git-repo-id goodmem/clients/js \
  --additional-properties=projectName=@pairsystems/goodmem-client,projectDescription="JavaScript client for GoodMem API",packageUrl=https://github.com/PAIR-Systems-Inc/goodmem/tree/main/clients/js,projectLicenseName=Apache-2.0,usePromises=true,moduleName=GoodMemClient

# Fix file permissions (Docker creates files as root)
echo "🔧 Fixing file permissions..."
sudo chown -R $(whoami):$(whoami) .
# Ensure build script itself remains executable
chmod +x "${CLIENT_DIR}/build.sh"

# Restore package.json if backup exists (preserves CI version updates)
if [ -f "package.json.backup" ]; then
    echo "📦 Restoring package.json from backup..."
    mv package.json.backup package.json
    echo "✅ Package.json restored with correct name and version"
fi

# Fix documentation to add StreamingClient examples
echo "🔧 Fixing documentation..."
if [ -f "fix_docs.js" ]; then
  chmod +x fix_docs.js
  node fix_docs.js
else
  echo "⚠️  fix_docs.js not found, skipping documentation fixes"
fi

# Fix README to add StreamingClient usage examples
echo "🔧 Fixing README..."
if [ -f "fix_readme.js" ]; then
  chmod +x fix_readme.js
  node fix_readme.js
else
  echo "⚠️  fix_readme.js not found, skipping README fixes"
fi

# Ensure StreamingClient is properly exported in index.js
echo "🔧 Ensuring StreamingClient is properly exported..."

# Check if streaming import exists
if ! grep -q "StreamingClient.*from.*streaming" src/index.js; then
    echo "⚠️  StreamingClient import not found, adding it..."
    
    # Find the line with UsersApi import and add streaming import after it
    sed -i '/import UsersApi from.*UsersApi/a import { StreamingClient, StreamError } from '"'"'./streaming.js'"'"';' src/index.js
fi

# Check if StreamingClient is exported (look for it in the export section)
if ! grep -A 20 "export {" src/index.js | grep -q "StreamingClient"; then
    echo "⚠️  StreamingClient export not found, adding it..."
    
    # Find the UsersApi export (last one without comma) and add comma + StreamingClient exports
    sed -i '/UsersApi$/c\    UsersApi,\
\
    /**\
    * The StreamingClient service constructor.\
    * @property {module:streaming\/StreamingClient}\
    */\
    StreamingClient,\
\
    /**\
    * The StreamError constructor.\
    * @property {module:streaming\/StreamError}\
    */\
    StreamError' src/index.js
    echo "✅ StreamingClient exports added"
else
    echo "✅ StreamingClient already exported"
fi

echo "✅ JavaScript client generated successfully"

# Step 2.5: Enhance README with authentication documentation
echo ""
echo "🔧 Step 2.5: Adding authentication documentation to README..."

# Replace the incorrect "no authorization" text
sed -i 's/Endpoints do not require authorization\./Authentication required - see configuration below./' README.md

# Update the getting started example to include authentication
sed -i '/var GoodMemClient = require/,/});/ {
    /var GoodMemClient = require/a\
\
// Configure the API client\
var defaultClient = GoodMemClient.ApiClient.instance;\
defaultClient.basePath = "http://localhost:8080";  // Use your server URL\
\
// Configure API key authentication: X-API-Key header\
defaultClient.defaultHeaders = {\
    "X-API-Key": "your-api-key-here",\
    "Content-Type": "application/json",\
    "Accept": "application/json"\
};
}' README.md

# Add authentication section before "Documentation for API Endpoints"
sed -i '/## Documentation for API Endpoints/i \
## Authentication\
\
Configure API key authentication by setting the X-API-Key header:\
\
```javascript\
var GoodMemClient = require("@pairsystems/goodmem-client");\
\
// Configure the API client\
var defaultClient = GoodMemClient.ApiClient.instance;\
defaultClient.basePath = "http://localhost:8080";  // Use your server URL\
\
// Configure API key authentication\
defaultClient.defaultHeaders = {\
    "X-API-Key": "your-api-key-here",\
    "Content-Type": "application/json",\
    "Accept": "application/json"\
};\
\
// Create API instances\
var apiKeysApi = new GoodMemClient.APIKeysApi();\
var spacesApi = new GoodMemClient.SpacesApi();\
```\
\
### Getting an API Key\
\
You can create an API key using the APIKeysApi:\
\
```javascript\
var createRequest = {\
    labels: {\
        "environment": "development",\
        "service": "your-app-name"\
    }\
};\
\
apiKeysApi.createApiKey(createRequest).then(function(response) {\
    console.log("API Key created successfully:");\
    console.log("Key ID:", response.apiKeyMetadata.apiKeyId);\
    console.log("Raw API Key:", response.rawApiKey);\
    console.log("Key Prefix:", response.apiKeyMetadata.keyPrefix);\
}, function(error) {\
    console.error("Error creating API key:", error);\
});\
```\
\
' README.md

# Also update the Authorization section at the bottom
sed -i 's/Endpoints do not require authorization\./Authentication schemes defined for the API:\
\
### ApiKeyAuth\
\
- **Type**: API key\
- **API key parameter name**: X-API-Key\
- **Location**: HTTP header\
\
Configure authentication by setting the X-API-Key header in defaultHeaders as shown in the examples above./' README.md

echo "✅ Authentication documentation added to README"

# Step 3: Install dependencies and build
echo ""
echo "🔧 Step 3: Installing dependencies and building JavaScript client..."

# Install dependencies
echo "📦 Installing npm dependencies..."
npm install

# Run build (optional - only if build script exists)
echo "🔨 Building JavaScript client..."
if npm run | grep -q "build"; then
    npm run build
else
    echo "ℹ️  No build script found, skipping build step (not required for this client)"
fi

# Run tests (but continue even if they fail)
echo "🧪 Running JavaScript tests..."
npm test || echo "⚠️  Tests failed, but continuing with build..."

# Step 3.5: Validate streaming functionality
echo ""
echo "🔧 Step 3.5: Validating streaming functionality..."

# Check if streaming files exist
streaming_files=("src/streaming.js" "src/client.js" "examples/streaming_example.js")
all_streaming_files_exist=true

for file in "${streaming_files[@]}"; do
    if [ -f "$file" ]; then
        echo "✅ Custom streaming file found: $file"
    else
        echo "❌ Missing streaming file: $file"
        all_streaming_files_exist=false
    fi
done

# Check if streaming client is properly exported
if grep -q "StreamingClient" src/index.js; then
    echo "✅ StreamingClient properly exported in index.js"
else
    echo "❌ StreamingClient not found in index.js exports"
    all_streaming_files_exist=false
fi

# Check if .openapi-generator-ignore contains streaming files
if [ -f ".openapi-generator-ignore" ]; then
    if grep -q "src/streaming.js" .openapi-generator-ignore; then
        echo "✅ Streaming files protected by .openapi-generator-ignore"
    else
        echo "❌ Streaming files not protected by .openapi-generator-ignore"
        all_streaming_files_exist=false
    fi
else
    echo "❌ .openapi-generator-ignore file not found"
    all_streaming_files_exist=false
fi

# Run a basic syntax check on streaming files
echo "🔍 Validating streaming file syntax..."
if command -v node &> /dev/null; then
    # Check streaming.js syntax
    if node -c src/streaming.js 2>/dev/null; then
        echo "✅ streaming.js syntax is valid"
    else
        echo "❌ streaming.js has syntax errors"
        all_streaming_files_exist=false
    fi
    
    # Check client.js syntax  
    if node -c src/client.js 2>/dev/null; then
        echo "✅ client.js syntax is valid"
    else
        echo "❌ client.js has syntax errors"
        all_streaming_files_exist=false
    fi
else
    echo "⚠️  Node.js not available for syntax validation"
fi

# Report validation results
if [ "$all_streaming_files_exist" = true ]; then
    echo "✅ Streaming functionality validation passed"
else
    echo "❌ Streaming functionality validation failed"
    echo "⚠️  Streaming features may not work correctly in the built package"
fi

echo "✅ JavaScript client build completed"

# Step 4: Package for distribution
echo ""
echo "🔧 Step 4: Packaging JavaScript client for distribution..."

# Create npm package
echo "📦 Creating npm package..."
npm pack

# Move package to dist directory
echo "📦 Moving package to dist directory..."
mv *.tgz "${DIST_DIR}/"

# Also copy source files for development
echo "📦 Copying source files..."
mkdir -p "${DIST_DIR}/src"
rsync -av --exclude='node_modules' --exclude='*.tgz' --exclude='.git' --exclude='dist' "${CLIENT_DIR}/" "${DIST_DIR}/src/"

# Final permissions fix to ensure everything is accessible
echo "🔧 Final permissions check..."
sudo chown -R $(whoami):$(whoami) .
chmod +x "${CLIENT_DIR}/build.sh"

# Check if packaging was successful
if ls "${DIST_DIR}"/*.tgz &>/dev/null; then
    echo "✅ JavaScript client built and packaged successfully!"
    echo "📂 Output files available in: ${DIST_DIR}/"
    echo ""
    echo "📋 Generated files:"
    ls -la "${DIST_DIR}/" | head -10
    echo ""
    echo "📦 Package details:"
    ls -la "${DIST_DIR}"/*.tgz
else
    echo "⚠️ Packaging failed. Expected files not found."
    exit 1
fi

echo ""
echo "🎉 JavaScript client build completed successfully!"
echo "   1. ✅ OpenAPI spec extracted from server"
echo "   2. ✅ JavaScript client code generated"  
echo "   3. ✅ Dependencies installed and built"
echo "   4. ✅ Streaming functionality validated"
echo "   5. ✅ NPM package created"
echo "   6. ✅ File permissions fixed"
echo ""
echo "📋 Package includes:"
echo "  - 🔄 Standard OpenAPI-generated client"
echo "  - 🚀 Custom streaming client for real-time memory retrieval"
echo "  - 📊 Similarity score ranking and processing"
echo "  - 📖 Usage examples and documentation"
echo ""
echo "Next steps:"
echo "  - Test the package locally with: npm install ${DIST_DIR}/*.tgz"
echo "  - Test streaming functionality with examples/streaming_example.js"
echo "  - Push to GitHub to trigger js-client-release.yml workflow"