name: Security and Dependency Scanning

on:
  push:
    branches:
      - main
      - master
  pull_request:
    branches:
      - main
      - master
  schedule:
    # Run security scan daily at 3 AM UTC
    - cron: '0 3 * * *'
  workflow_dispatch:

env:
  NODE_VERSION: '20'

jobs:
  dependency-scan:
    name: Dependency Security Scan
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --no-audit --no-fund

      - name: Run npm audit
        run: |
          echo "Running npm security audit..."
          npm audit --audit-level=moderate --json > audit-results.json || true
          
          # Extract vulnerability counts
          HIGH_VULNS=$(cat audit-results.json | jq '.metadata.vulnerabilities.high // 0')
          CRITICAL_VULNS=$(cat audit-results.json | jq '.metadata.vulnerabilities.critical // 0')
          
          echo "High vulnerabilities: $HIGH_VULNS"
          echo "Critical vulnerabilities: $CRITICAL_VULNS"
          
          # Fail if critical vulnerabilities found
          if [ "$CRITICAL_VULNS" -gt 0 ]; then
            echo "❌ Critical vulnerabilities found!"
            cat audit-results.json | jq '.vulnerabilities[] | select(.severity == "critical")'
            exit 1
          fi
          
          # Warn if high vulnerabilities found
          if [ "$HIGH_VULNS" -gt 0 ]; then
            echo "⚠️ High vulnerabilities found!"
            cat audit-results.json | jq '.vulnerabilities[] | select(.severity == "high")'
          fi

      - name: License check
        run: |
          echo "Checking package licenses..."
          npx license-checker --summary --onlyAllow 'MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;Unlicense;CC0-1.0' || {
            echo "⚠️ Some packages have non-approved licenses"
            echo "Run 'npx license-checker --summary' to see details"
          }

      - name: Check for outdated packages
        run: |
          echo "Checking for outdated packages..."
          npm outdated --json > outdated-packages.json || true
          
          # Count outdated packages
          OUTDATED_COUNT=$(cat outdated-packages.json | jq 'length')
          echo "Outdated packages: $OUTDATED_COUNT"
          
          if [ "$OUTDATED_COUNT" -gt 0 ]; then
            echo "⚠️ Found $OUTDATED_COUNT outdated packages"
            cat outdated-packages.json | jq 'keys[]'
          fi

      - name: Upload security results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: security-scan-results
          path: |
            audit-results.json
            outdated-packages.json
          retention-days: 30

  code-security-scan:
    name: Code Security Scan
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci --no-audit --no-fund

      - name: Install security tools
        run: |
          npm install -g @eslint/eslintrc
          npm install -g eslint-plugin-security

      - name: Security linting
        run: |
          echo "Running security-focused linting..."
          # Check for common security issues
          if grep -r "eval(" --include="*.js" --include="*.ts" --include="*.tsx" .; then
            echo "❌ Found eval() usage - potential security risk"
            exit 1
          fi
          
          if grep -r "innerHTML" --include="*.js" --include="*.ts" --include="*.tsx" .; then
            echo "⚠️ Found innerHTML usage - review for XSS risks"
          fi
          
          if grep -r "dangerouslySetInnerHTML" --include="*.js" --include="*.ts" --include="*.tsx" .; then
            echo "⚠️ Found dangerouslySetInnerHTML usage - review for XSS risks"
          fi

      - name: Check for hardcoded secrets
        run: |
          echo "Checking for potential hardcoded secrets..."
          # Check for common secret patterns
          if grep -rE "(password|secret|key|token).*=.*['\"][^'\"]{8,}['\"]" --include="*.js" --include="*.ts" --include="*.tsx" --exclude-dir=node_modules .; then
            echo "⚠️ Potential hardcoded secrets found - review manually"
          fi
          
          # Check for API keys
          if grep -rE "(api[_-]?key|apikey)" --include="*.js" --include="*.ts" --include="*.tsx" --exclude-dir=node_modules .; then
            echo "⚠️ Potential API key references found - ensure no hardcoded keys"
          fi

      - name: Check environment variable usage
        run: |
          echo "Checking environment variable usage..."
          # Ensure sensitive data uses environment variables
          if grep -r "process\.env\." --include="*.js" --include="*.ts" --include="*.tsx" .; then
            echo "✅ Environment variables are being used"
          fi

  container-security:
    name: Container Security Scan
    runs-on: ubuntu-latest
    timeout-minutes: 10
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Check Dockerfile security
        run: |
          if [ -f "Dockerfile" ]; then
            echo "Checking Dockerfile security..."
            
            # Check for root user
            if grep -q "USER root" Dockerfile; then
              echo "⚠️ Dockerfile runs as root - consider using non-root user"
            fi
            
            # Check for latest tags
            if grep -q ":latest" Dockerfile; then
              echo "⚠️ Dockerfile uses 'latest' tag - consider pinning versions"
            fi
            
            # Check for security updates
            if grep -q "apt-get update" Dockerfile; then
              echo "✅ Dockerfile includes package updates"
            fi
          else
            echo "No Dockerfile found - skipping container security check"
          fi

  security-report:
    name: Generate Security Report
    runs-on: ubuntu-latest
    timeout-minutes: 5
    needs: [dependency-scan, code-security-scan, container-security]
    if: always()
    steps:
      - name: Download security results
        uses: actions/download-artifact@v4
        with:
          name: security-scan-results
          path: security-results/

      - name: Generate security report
        run: |
          echo "# Security Scan Report" > security-report.md
          echo "Generated: $(date -u)" >> security-report.md
          echo "" >> security-report.md
          
          # Add dependency scan results
          if [ -f "security-results/audit-results.json" ]; then
            echo "## Dependency Security" >> security-report.md
            echo "" >> security-report.md
            
            CRITICAL=$(cat security-results/audit-results.json | jq '.metadata.vulnerabilities.critical // 0')
            HIGH=$(cat security-results/audit-results.json | jq '.metadata.vulnerabilities.high // 0')
            MODERATE=$(cat security-results/audit-results.json | jq '.metadata.vulnerabilities.moderate // 0')
            LOW=$(cat security-results/audit-results.json | jq '.metadata.vulnerabilities.low // 0')
            
            echo "- Critical: $CRITICAL" >> security-report.md
            echo "- High: $HIGH" >> security-report.md
            echo "- Moderate: $MODERATE" >> security-report.md
            echo "- Low: $LOW" >> security-report.md
            echo "" >> security-report.md
          fi
          
          # Add outdated packages
          if [ -f "security-results/outdated-packages.json" ]; then
            echo "## Outdated Packages" >> security-report.md
            echo "" >> security-report.md
            
            OUTDATED_COUNT=$(cat security-results/outdated-packages.json | jq 'length')
            echo "Total outdated packages: $OUTDATED_COUNT" >> security-report.md
            echo "" >> security-report.md
          fi
          
          echo "## Scan Status" >> security-report.md
          echo "" >> security-report.md
          echo "- Dependency Scan: ${{ needs.dependency-scan.result }}" >> security-report.md
          echo "- Code Security Scan: ${{ needs.code-security-scan.result }}" >> security-report.md
          echo "- Container Security: ${{ needs.container-security.result }}" >> security-report.md

      - name: Upload security report
        uses: actions/upload-artifact@v4
        with:
          name: security-report
          path: security-report.md
          retention-days: 90

      - name: Comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const report = fs.readFileSync('security-report.md', 'utf8');
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🔒 Security Scan Results
              
              ${report}`
            });
