#!/bin/bash

# ANSI color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

echo -e "${BLUE}🔒 BWS Secure Installation Started${NC}"

# Determine the execution context
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# Check if we're running from within node_modules
if [[ "$SCRIPT_DIR" == *"node_modules/bws-secure"* ]] || [[ "$SCRIPT_DIR" == *"node_modules/.pnpm/bws-secure"* ]]; then
  echo -e "${BLUE}🔒 Detected installation from npm package${NC}"
  
  # Get project root (where the package.json is)
  PROJECT_ROOT="$(pwd)"
  
  # Make sure we can find the node_modules directory
  if [ ! -d "$PROJECT_ROOT/node_modules" ]; then
    # Try going up until we find node_modules or reach filesystem root
    current="$PROJECT_ROOT"
    while [ "$current" != "/" ] && [ ! -d "$current/node_modules" ]; do
      current="$(dirname "$current")"
    done
    
    if [ -d "$current/node_modules" ]; then
      PROJECT_ROOT="$current"
    fi
  fi
  
  echo -e "${BLUE}🔒 Project Root: ${PROJECT_ROOT}${NC}"
  
  # Make files executable
  find "$SCRIPT_DIR" -name "*.js" -exec chmod +x {} \;
  find "$SCRIPT_DIR" -name "*.sh" -exec chmod +x {} \;
  
  # Create the bin directory in node_modules/.bin ONLY (not in project root)
  BIN_DIR="${PROJECT_ROOT}/node_modules/.bin"
  mkdir -p "$BIN_DIR"
  
  # Create the executables in the bin directory
  echo "#!/bin/bash" > "${BIN_DIR}/secure-run"
  echo "node ${SCRIPT_DIR}/secureRun.js \"\$@\"" >> "${BIN_DIR}/secure-run"
  chmod +x "${BIN_DIR}/secure-run"
  
  echo "#!/bin/bash" > "${BIN_DIR}/bws-list"
  echo "node ${SCRIPT_DIR}/list-projects.js \"\$@\"" >> "${BIN_DIR}/bws-list"
  chmod +x "${BIN_DIR}/bws-list"
  
  echo "#!/bin/bash" > "${BIN_DIR}/bws-upload"
  echo "node ${SCRIPT_DIR}/upload-to-bws/upload-secrets.js \"\$@\"" >> "${BIN_DIR}/bws-upload"
  chmod +x "${BIN_DIR}/bws-upload"
  
  echo "#!/bin/bash" > "${BIN_DIR}/bws-scan"
  echo "node ${SCRIPT_DIR}/check-vars/requiredRuntimeVars.js \"\$@\"" >> "${BIN_DIR}/bws-scan"
  chmod +x "${BIN_DIR}/bws-scan"
  
  # Install Bitwarden CLI if not already present or is corrupted
  if [ ! -x "${BIN_DIR}/bws" ] || [ ! -s "${BIN_DIR}/bws" ]; then
    echo -e "${BLUE}🔒 Installing Bitwarden CLI...${NC}"
    
    # First, try to use npm to install the Bitwarden CLI globally
    npm install -g @bitwarden/cli

    # Create a symbolic link to the global bws executable in node_modules/.bin ONLY
    if command -v bws >/dev/null 2>&1; then
      # Get the path to the global bws executable
      BWS_PATH=$(which bws)
      echo -e "${BLUE}🔒 Found Bitwarden CLI at: $BWS_PATH${NC}"
      
      # Create symlink in node_modules/.bin only
      ln -sf "$BWS_PATH" "${BIN_DIR}/bws"
      echo -e "${BLUE}🔒 Created symlink from ${BIN_DIR}/bws to $BWS_PATH${NC}"
      
      if [ -x "${BIN_DIR}/bws" ]; then
        echo -e "${BLUE}🔒 Bitwarden CLI installed successfully!${NC}"
      else
        echo -e "${RED}❌ Failed to create symlink for Bitwarden CLI. Please install it manually.${NC}"
        exit 1
      fi
    else
      echo -e "${RED}❌ Failed to install Bitwarden CLI using npm. Please install it manually.${NC}"
      exit 1
    fi
  fi
  
  # Detect package manager
  if [ -f "${PROJECT_ROOT}/pnpm-lock.yaml" ]; then
    PM="pnpm"
  elif [ -f "${PROJECT_ROOT}/yarn.lock" ]; then
    PM="yarn"
  else
    PM="npm"
  fi
  
  # Always check for and create bwsconfig.json in the project root
  echo -e "${BLUE}🔒 Checking for bwsconfig.json in project root...${NC}"
  if [ -f "${PROJECT_ROOT}/bwsconfig.json" ]; then
    echo -e "${BLUE}🔒 Found existing bwsconfig.json at: ${PROJECT_ROOT}/bwsconfig.json${NC}"
  else
    # Create default config if it doesn't exist
    echo -e "${BLUE}🔒 Creating default bwsconfig.json...${NC}"
    cat > "${PROJECT_ROOT}/bwsconfig.json" << EOF
{
  "projects": [
    {
      "platform": "vercel|netlify",
      "projectName": "firstProjectName",
      "bwsProjectIds": {
        "prod": "yourBWSProdProjectID",
        "dev": "yourBWSDevProjectID",
        "local": "yourBWSLocalProjectID"
      },
      "preserveVars": ["BWS_ACCESS_TOKEN"],
      "excludeVars": [
        "VERCEL_URL"
      ]
    },
    {
      "platform": "vercel|netlify",
      "projectName": "secondProjectName",
      "bwsProjectIds": {
        "prod": "yourBWSProdProjectID",
        "dev": "yourBWSDevProjectID",
        "local": "yourBWSLocalProjectID"
      },
      "preserveVars": ["BWS_ACCESS_TOKEN"],
      "excludeVars": [
        "DEPLOY_URL"
      ]
    }
  ]
}
EOF
  fi
  
  # Create README.md in the project root if it doesn't exist
  if [ ! -f "${PROJECT_ROOT}/BWS-README.md" ]; then
    echo -e "${BLUE}🔒 Creating BWS-README.md in project root...${NC}"
    cat > "${PROJECT_ROOT}/BWS-README.md" << 'EOF'
# BWS Secure

BWS Secure is a tool for managing secure environment variables using Bitwarden Secrets Manager.

## Getting Started

1. Install the Bitwarden CLI: This is done automatically during installation.
2. Set up a Bitwarden Secrets Manager account at [https://bitwarden.com/](https://bitwarden.com/)
3. Create a project and get an access token.
4. Add the access token to your environment as `BWS_ACCESS_TOKEN`.

## Usage

The following commands are available:

- `npx secure-run <command>` - Run a command with secrets from Bitwarden Secrets Manager
- `npx bws-list` - List available Bitwarden projects
- `npx bws-upload` - Upload environment variables to Bitwarden Secrets Manager
- `npx bws-scan` - Scan for required environment variables

## Documentation

For more information, visit [https://bitwarden.com/help/secrets-manager-overview/](https://bitwarden.com/help/secrets-manager-overview/)
EOF
  fi
  
  # Update .gitignore
  if [ -f "${PROJECT_ROOT}/.gitignore" ]; then
    echo -e "${BLUE}🔒 Checking .gitignore configuration...${NC}"
    # Update .gitignore
    GITIGNORE_ENTRIES=(
      " "
      "# BWS Secure"
      ".env"
      ".env.*"
      ".env.secure.*"
      "requiredVars.env"
      ".env-debug.html"
    )
    
    # Check if entries already exist in .gitignore
    for entry in "${GITIGNORE_ENTRIES[@]}"; do
      if ! grep -Fxq "$entry" "${PROJECT_ROOT}/.gitignore"; then
        echo "$entry" >> "${PROJECT_ROOT}/.gitignore"
      fi
    done
  fi
  
  # Create .env file if it doesn't exist
  if [ ! -f "${PROJECT_ROOT}/.env" ]; then
    echo -e "${BLUE}🔒 Creating .env file...${NC}"
    cat > "${PROJECT_ROOT}/.env" << EOF
# BWS Secure Configuration
BWS_ACCESS_TOKEN=your_token_here
EOF
  fi
  
  # Update .prettierignore if it exists
  if [ -f "${PROJECT_ROOT}/.prettierignore" ]; then
    echo -e "${BLUE}🔒 Checking Prettier configuration...${NC}"
    # Create or update .prettierignore
    PRETTIER_ENTRIES=(
      " "
      "# BWS Secure - Environment Files"
      ".env"
      ".env.*"
      "*.env"
      ".env.secure"
      ".env.secure.*"
    )
    
    # Add a blank line if file exists and doesn't end with one
    if [ -s "${PROJECT_ROOT}/.prettierignore" ]; then
      if [ "$(tail -c1 "${PROJECT_ROOT}/.prettierignore" | wc -l)" -eq 0 ]; then
        echo "" >> "${PROJECT_ROOT}/.prettierignore"
      fi
    fi
    
    # Check if BWS Secure section header exists
    if ! grep -q "# BWS Secure - Environment Files" "${PROJECT_ROOT}/.prettierignore"; then
      # Add a blank line before our section if file is not empty
      if [ -s "${PROJECT_ROOT}/.prettierignore" ]; then
        echo "" >> "${PROJECT_ROOT}/.prettierignore"
      fi
    fi
    
    # Check if entries already exist in .prettierignore
    for entry in "${PRETTIER_ENTRIES[@]}"; do
      if ! grep -Fxq "$entry" "${PROJECT_ROOT}/.prettierignore"; then
        echo "$entry" >> "${PROJECT_ROOT}/.prettierignore"
      fi
    done
    
    # Ensure file ends with a newline
    if [ -s "${PROJECT_ROOT}/.prettierignore" ] && [ "$(tail -c1 "${PROJECT_ROOT}/.prettierignore" | wc -l)" -eq 0 ]; then
      echo "" >> "${PROJECT_ROOT}/.prettierignore"
    fi
  fi
  
  # Check README files for BWS Secure documentation
  echo -e "${BLUE}🔒 Checking README files for BWS Secure documentation...${NC}"
  README_FILES=("README.md" "Readme.md" "readme.md")
  README_FOUND=false
  
  # Define the BWS Secure documentation content
  BWS_DOC_CONTENT="<!-- BWS-SECURE-DOCS-START -->
## BWS Secure Environmental Variable Integration

This project uses [BWS Secure](https://github.com/last-rev-llc/bws-secure) for managing environment variables across different environments.

### Creating an Access Token

1. Visit the [Last Rev Bitwarden Machine Accounts](https://vault.bitwarden.com/#/sm/22479128-f194-460a-884b-b24a015686c6/machine-accounts) section
   - **Note:** This link requires you to be a member of the Last Rev Bitwarden organization
   - If you don't have access, please refer to the [BWS Secure documentation](https://github.com/last-rev-llc/bws-secure) or contact your team administrator
2. After clicking the link, follow these steps:
   - Select the appropriate Client/Set of Machine Accounts from the list
   - Click on the \"Access Tokens\" tab
   - Click \"+ New Access Token\" button
   - Give the token a meaningful name (e.g., \"Your Name - Local Development\")
   - Click \"Save\" to generate the token
3. Copy the displayed token (you won't be able to see it again after closing)
4. Add it to your .env file in your project root:
   \`\`\`
   BWS_ACCESS_TOKEN=your_token_here
   \`\`\`
5. Never commit this token to version control

### Updating BWS Secure

To update the BWS Secure integration to the latest version, run:

\`\`\`bash
npm install bws-secure@latest
\`\`\`
<!-- BWS-SECURE-DOCS-END -->"
  
  for README_FILE in "${README_FILES[@]}"; do
    if [ -f "${PROJECT_ROOT}/${README_FILE}" ]; then
      README_FOUND=true
      
      # Check if BWS Secure section already exists
      if grep -q "<!-- BWS-SECURE-DOCS-START -->" "${PROJECT_ROOT}/${README_FILE}" && grep -q "<!-- BWS-SECURE-DOCS-END -->" "${PROJECT_ROOT}/${README_FILE}"; then
        echo -e "${BLUE}🔒 BWS Secure documentation markers found in ${README_FILE}, updating content...${NC}"
        
        # Create a temporary file
        TMP_FILE=$(mktemp)
        
        # Extract everything before the start marker
        sed -n '1,/<!-- BWS-SECURE-DOCS-START -->/p' "${PROJECT_ROOT}/${README_FILE}" | sed '$d' > "$TMP_FILE"
        
        # Add the updated BWS documentation
        echo -e "$BWS_DOC_CONTENT" >> "$TMP_FILE"
        
        # Extract everything after the end marker
        sed -n '/<!-- BWS-SECURE-DOCS-END -->/,$p' "${PROJECT_ROOT}/${README_FILE}" | sed '1d' >> "$TMP_FILE"
        
        # Replace the original file with the updated content
        mv "$TMP_FILE" "${PROJECT_ROOT}/${README_FILE}"
      else
        echo -e "${BLUE}🔒 Adding BWS Secure documentation to ${README_FILE}...${NC}"
        
        # Add newline at end of file if not present
        if [ -s "${PROJECT_ROOT}/${README_FILE}" ] && [ "$(tail -c1 "${PROJECT_ROOT}/${README_FILE}" | wc -l)" -eq 0 ]; then
          echo "" >> "${PROJECT_ROOT}/${README_FILE}"
        fi
        
        # Append BWS Secure documentation with markers
        echo -e "\n$BWS_DOC_CONTENT" >> "${PROJECT_ROOT}/${README_FILE}"
      fi
      break
    fi
  done
  
  if [ "$README_FOUND" = false ]; then
    echo -e "${BLUE}🔒 No README file found in ${PROJECT_ROOT}. Creating README.md with BWS Secure documentation...${NC}"
    
    # Create a new README with the BWS documentation
    cat > "${PROJECT_ROOT}/README.md" << EOF
# Project Documentation

$BWS_DOC_CONTENT
EOF
  fi
  
  # Update package.json with scripts if it exists
  if [ -f "${PROJECT_ROOT}/package.json" ]; then
    echo -e "${BLUE}🔒 Updating package.json at: ${PROJECT_ROOT}/package.json${NC}"
    
    TMP_SCRIPT=$(mktemp)
    cat > "$TMP_SCRIPT" << EOF
const fs = require('fs');
try {
  // Use absolute path to package.json
  const packageJsonPath = '${PROJECT_ROOT}/package.json';
  const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));

  // Ensure scripts object exists
  packageJson.scripts = packageJson.scripts || {};

  // Add our core scripts
  packageJson.scripts['secure-run'] = 'secure-run';
  packageJson.scripts['list-projects'] = 'bws-list';
  packageJson.scripts['bws-deps'] = '[ -d node_modules/dotenv ] && [ -d node_modules/dotenv-cli ] && [ -f node_modules/.bin/bws ] || npm install';

  // Check for and fix incorrect secure-run.js references in any scripts
  for (const [scriptName, scriptCommand] of Object.entries(packageJson.scripts)) {
    if (scriptCommand.includes('secure-run.js')) {
      console.log(\`Fixing incorrect secure-run.js reference in \${scriptName} script\`);
      packageJson.scripts[scriptName] = scriptCommand.replace(/secure-run\.js/g, 'secureRun.js');
    }
  }

  // Write back to file
  fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
  process.exit(0);
} catch (error) {
  console.error('Error updating package.json:', error);
  process.exit(1);
}
EOF
    
    # Run the temporary Node.js script
    if node "$TMP_SCRIPT"; then
      echo -e "${BLUE}🔒 Updated package.json successfully${NC}"
    else
      echo -e "${RED}❌ Warning: Failed to update package.json scripts. You may need to add them manually.${NC}"
    fi
    
    # Clean up temporary script
    rm -f "$TMP_SCRIPT"
  fi
  
  # Success message with box drawing characters
  echo -e "
${GREEN}╔════════════════════════════════════════════════════════════╗
║             ✅ BWS Secure Setup Complete!                  ║
╚════════════════════════════════════════════════════════════╝${NC}

📋 Next Steps:

1. Configure your bwsconfig.json at:
   ${PROJECT_ROOT}/bwsconfig.json
   - Set platform to 'vercel' or 'netlify'
   - Update projectName to match your deployment
   - Add your BWS project IDs for each environment

2. Add your BWS token to .env:
   BWS_ACCESS_TOKEN=your_token_here

3. Update your build scripts to use secure-run:
   \"dev\": \"secure-run next dev\"
   \"build\": \"secure-run next build\"
   \"start\": \"secure-run next start\"

🔧 Added Scripts:
   - secure-run: Runs commands with secure environment variables
   - list-projects: Lists available BWS projects
   - bws-deps: Ensures BWS dependencies are installed

📦 Dependencies:
   - BWS CLI will be installed automatically when needed
   - Required packages have been added as dependencies
   - Run '$PM bws-deps' to verify BWS installation

🔒 Security:
   - Environment files are encrypted
   - .gitignore has been updated
   - Secrets are never logged

📚 Documentation: https://github.com/last-rev-llc/bws-secure

For help or issues:
1. Check the README.md in your project
2. Enable debug mode: DEBUG=true $PM build
3. Open an issue on GitHub
"
  
  echo -e "${GREEN}✅ BWS Secure installation completed successfully${NC}"
  exit 0
else
  # Standard installation - simplified to use the current directory
  echo -e "${BLUE}🔒 Running standard installation${NC}"
  
  # Determine if we're in the monorepo root or the package directory
  if [ -f "package.json" ] && [ -d "node_modules" ]; then
    # We're in the package directory
    echo -e "${BLUE}🔒 Setting up BWS Secure in $(pwd)${NC}"
    
    # Create scripts directory if it doesn't exist
    mkdir -p scripts
    
    # Helper function to check and initialize git submodules if needed
    check_git_submodules() {
      # Check if .gitmodules exists
      if [ -f ".gitmodules" ]; then
        echo "Git submodules detected, checking status..."
        
        # Check if any submodules are uninitialized (have no .git directory)
        UNINITIALIZED_SUBMODULES=$(git submodule status | grep "^-" | wc -l)
        
        if [ "$UNINITIALIZED_SUBMODULES" -gt 0 ]; then
          echo "Found uninitialized git submodules. Initializing them now..."
          git submodule update --init
          return 0  # Submodules were initialized
        fi
      fi
      return 1  # No submodules initialized
    }

    # Call the function to check for submodules before starting
    check_git_submodules

    # Create bin directory if it doesn't exist
    mkdir -p bin

    # Make scripts executable (only if they exist)
    if [ -d "./bin" ] && [ "$(ls -A ./bin)" ]; then
      chmod +x ./bin/*
    fi
    [ -f "./bws-installer.sh" ] && chmod +x ./bws-installer.sh

    # Detect package manager
    if [ -f "../../pnpm-lock.yaml" ]; then
      PM="pnpm"
    elif [ -f "../../yarn.lock" ]; then
      PM="yarn"
    else
      PM="npm"
    fi

    # Check Node.js version for compatibility
    NODE_VERSION=$(node -e "console.log(process.version.match(/^v(\d+)\./)[1])")
    if [ "$NODE_VERSION" -lt "20" ]; then
      echo "Detected Node.js v$NODE_VERSION, ensuring compatible glob version (v10) for Node.js v$NODE_VERSION"
      
      # Update BWS Secure's own package.json to use compatible glob version
      if [ -f "package.json" ]; then
        echo "Updating BWS Secure package.json to use glob v10.3.10 compatible with Node.js v$NODE_VERSION..."
        
        # Create temporary script to update BWS package.json
        BWS_TMP_SCRIPT=$(mktemp)
        cat > "$BWS_TMP_SCRIPT" << EOF
        const fs = require('fs');
        try {
          const packageJsonPath = '$(pwd)/package.json';
          const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
          
          // Update glob version to compatible one
          if (packageJson.dependencies && packageJson.dependencies.glob) {
            packageJson.dependencies.glob = '^10.3.10';
          }
          
          // Write back to file
          fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
          process.exit(0);
        } catch (error) {
          console.error('Error updating BWS package.json:', error);
          process.exit(1);
        }
EOF
        
        # Run the temporary Node.js script
        if node "$BWS_TMP_SCRIPT"; then
          echo "Updated BWS Secure package.json with compatible glob version"
        else
          echo "Warning: Failed to update BWS Secure package.json"
        fi
        
        # Clean up temporary script
        rm -f "$BWS_TMP_SCRIPT"
      fi
    fi
    
    # Copy example config if it doesn't exist
    if [ ! -f "../bwsconfig.json" ] && [ -f "./examples/bwsconfig.example.json" ]; then
      echo "Creating bwsconfig.json from example..."
      cp ./examples/bwsconfig.example.json ../bwsconfig.json
    else
      echo "Checking for bwsconfig.json in project root..."
      if [ -f "../bwsconfig.json" ]; then
        echo "Found existing bwsconfig.json at: ../bwsconfig.json"
      else
        # Create default config if example doesn't exist
        echo "Creating default bwsconfig.json..."
        cat > ../bwsconfig.json << EOF
{
  "projects": [
    {
      "platform": "vercel|netlify",
      "projectName": "firstProjectName",
      "bwsProjectIds": {
        "prod": "yourBWSProdProjectID",
        "dev": "yourBWSDevProjectID",
        "local": "yourBWSLocalProjectID"
      },
      "preserveVars": ["BWS_ACCESS_TOKEN"],
      "excludeVars": [
        "VERCEL_URL"
      ]
    },
    {
      "platform": "vercel|netlify",
      "projectName": "secondProjectName",
      "bwsProjectIds": {
        "prod": "yourBWSProdProjectID",
        "dev": "yourBWSDevProjectID",
        "local": "yourBWSLocalProjectID"
      },
      "preserveVars": ["BWS_ACCESS_TOKEN"],
      "excludeVars": [
        "DEPLOY_URL"
      ]
    }
  ]
}
EOF
      fi
    fi
    
    # Success message with box drawing characters
    echo -e "
${GREEN}╔════════════════════════════════════════════════════════════╗
║             ✅ BWS Secure Setup Complete!                  ║
╚════════════════════════════════════════════════════════════╝${NC}

📋 Next Steps:

1. Configure your bwsconfig.json
   - Set platform to 'vercel' or 'netlify'
   - Update projectName to match your deployment
   - Add your BWS project IDs for each environment

2. Add your BWS token to .env:
   BWS_ACCESS_TOKEN=your_token_here

3. Update your build scripts to use secure-run:
   \"dev\": \"secure-run next dev\"
   \"build\": \"secure-run next build\"
   \"start\": \"secure-run next start\"

🔧 Added Scripts:
   - secure-run: Runs commands with secure environment variables
   - list-projects: Lists available BWS projects
   - bws-deps: Ensures BWS dependencies are installed

🔒 Security:
   - Environment files are encrypted
   - Secrets are never logged

📚 Documentation: https://github.com/last-rev-llc/bws-secure
"
  fi
fi

echo -e "${GREEN}✅ BWS Secure installation completed successfully${NC}" 