name: Security Testing (SAST & DAST)

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main, develop ]
  schedule:
    # Run security scans daily at 2 AM
    - cron: '0 2 * * *'

jobs:
  sast-eslint-security:
    name: SAST - ESLint Security Plugin
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: |
            frontend/package-lock.json
            backend/package-lock.json
      
      - name: Install backend dependencies
        run: cd backend && npm ci
      
      - name: Install frontend dependencies
        run: cd frontend && npm ci
      
      - name: Run ESLint Security Scan (Backend)
        run: cd backend && npx eslint . --ext .js --format json --output-file ../eslint-backend-report.json || true
      
      - name: Run ESLint Security Scan (Frontend)
        run: cd frontend && npx eslint . --ext .js,.jsx --format json --output-file ../eslint-frontend-report.json || true
      
      - name: Upload ESLint Reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: eslint-security-reports
          path: |
            eslint-backend-report.json
            eslint-frontend-report.json

  sast-semgrep:
    name: SAST - Semgrep
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Run Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: >-
            p/security-audit
            p/nodejs
            p/javascript
            p/express
            p/sql-injection
            p/xss
            p/command-injection
          generateSarif: true
      
      - name: Upload SARIF file
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: semgrep.sarif

  sast-npm-audit:
    name: SAST - NPM Audit
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Run NPM Audit (Backend)
        run: |
          cd backend
          npm audit --json > ../npm-audit-backend.json || true
          npm audit --audit-level=high
        continue-on-error: true
      
      - name: Run NPM Audit (Frontend)
        run: |
          cd frontend
          npm audit --json > ../npm-audit-frontend.json || true
          npm audit --audit-level=high
        continue-on-error: true
      
      - name: Upload NPM Audit Reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: npm-audit-reports
          path: |
            npm-audit-backend.json
            npm-audit-frontend.json

  sast-snyk:
    name: SAST - Snyk
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Run Snyk to check for vulnerabilities
        uses: snyk/actions/node@master
        continue-on-error: true
        env:
          SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
        with:
          args: --severity-threshold=high --all-projects

  docker-security-scan:
    name: SAST - Docker Image Security
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Build Docker image
        run: docker build -t streamflow-test:latest .
      
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'streamflow-test:latest'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
      
      - name: Upload Trivy results to GitHub Security
        uses: github/codeql-action/upload-sarif@v3
        if: always()
        with:
          sarif_file: 'trivy-results.sarif'
      
      - name: Run Dockle
        run: |
          wget -q https://github.com/goodwithtech/dockle/releases/download/v0.4.14/dockle_0.4.14_Linux-64bit.tar.gz
          tar zxf dockle_0.4.14_Linux-64bit.tar.gz
          ./dockle streamflow-test:latest

  dast-zap-scan:
    name: DAST - OWASP ZAP
    runs-on: ubuntu-latest
    needs: [sast-eslint-security, sast-semgrep]
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Start application in Docker
        run: |
          docker compose up -d
          sleep 30
      
      - name: Wait for application to be ready
        run: |
          timeout 60 bash -c 'until curl -f http://localhost:12345/api/health; do sleep 2; done'
      
      - name: Run OWASP ZAP Baseline Scan
        uses: zaproxy/action-baseline@v0.11.0
        with:
          target: 'http://localhost:12345'
          rules_file_name: '.zap/rules.tsv'
          cmd_options: '-a'
          fail_action: false
      
      - name: Run OWASP ZAP Full Scan
        uses: zaproxy/action-full-scan@v0.9.0
        with:
          target: 'http://localhost:12345'
          rules_file_name: '.zap/rules.tsv'
          cmd_options: '-a'
          fail_action: false
      
      - name: Stop application
        if: always()
        run: docker compose down
      
      - name: Upload ZAP Reports
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: zap-scan-reports
          path: |
            report_html.html
            report_json.json
            report_md.md

  security-report:
    name: Generate Security Report
    runs-on: ubuntu-latest
    needs: [sast-eslint-security, sast-semgrep, sast-npm-audit, docker-security-scan, dast-zap-scan]
    if: always()
    
    steps:
      - name: Download all artifacts
        uses: actions/download-artifact@v4
      
      - name: Generate summary report
        run: |
          echo "# Security Scan Summary" > security-report.md
          echo "" >> security-report.md
          echo "## Scan Date: $(date)" >> security-report.md
          echo "" >> security-report.md
          echo "### SAST Scans Completed:" >> security-report.md
          echo "- ✅ ESLint Security Plugin" >> security-report.md
          echo "- ✅ Semgrep" >> security-report.md
          echo "- ✅ NPM Audit" >> security-report.md
          echo "- ✅ Docker Image Scan (Trivy & Dockle)" >> security-report.md
          echo "" >> security-report.md
          echo "### DAST Scans Completed:" >> security-report.md
          echo "- ✅ OWASP ZAP Baseline Scan" >> security-report.md
          echo "- ✅ OWASP ZAP Full Scan" >> security-report.md
          echo "" >> security-report.md
          echo "### Artifacts:" >> security-report.md
          echo "All scan reports have been uploaded as workflow artifacts." >> security-report.md
      
      - name: Upload Security Report
        uses: actions/upload-artifact@v4
        with:
          name: security-summary-report
          path: security-report.md
