name: ✅⌛

on:
  workflow_dispatch:
  pull_request:
    branches:
      - main
      - develop
  push:
    branches:
      - main
      - develop
    paths:
      - 'Dockerfile'
      - 'docker-entrypoint.sh'
      - 'tools/*'
      - '.github/workflows/release.yml'
      - '.github/workflows/validate.yml'
      - 'templates/**'
      - 'compose*.yml'
      - 'docker-compose*.yml'
      - '.github/dependabot.yml'
      - '.github/renovate.json'
      - '!**/*.md'
      - '!**/*.txt'
      - '!docs/**'
      - '!LICENSE*'
      - '!CONTRIBUTING*'
      - '!CHANGELOG.md'
      - '!SECURITY.md'
      - '!CODE_OF_CONDUCT.md'

permissions:
  contents: read

jobs:
  lint:
    name: 🔍 Lint and Validate
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Repository
        uses: actions/checkout@v5

      - name: 🐳 Lint Dockerfile with Hadolint
        uses: hadolint/hadolint-action@v3.3.0
        with:
          dockerfile: Dockerfile
          failure-threshold: warning
        continue-on-error: true

      - name: 🔍 Validate Dockerfile Syntax
        run: |
          echo "🐳 Validating Dockerfile build context..."
          docker build --no-cache -t tor-relay-test .
          echo "✅ Dockerfile syntax valid"

      - name: 📝 Lint Shell Scripts
        run: |
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "🔍 Checking Shell Script Syntax"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo ""
          
          # Check main entrypoint script
          if [ -f docker-entrypoint.sh ]; then
            echo "📄 Checking docker-entrypoint.sh..."
            sh -n docker-entrypoint.sh || exit 1
            echo "   ✅ docker-entrypoint.sh syntax valid"
          fi

          echo ""
          echo "📁 Checking tools directory (no .sh extension)..."

          # Check if tools directory exists
          if [ ! -d "tools" ]; then
            echo "   ⚠️  tools/ directory not found"
          else
            # Check all files in tools/ (no .sh extension)
            TOOL_COUNT=0
            for script in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth; do
              if [ -f "$script" ]; then
                echo "📄 Checking $(basename "$script")..."
                sh -n "$script" || exit 1
                echo "   ✅ $script syntax valid"
                TOOL_COUNT=$((TOOL_COUNT + 1))
              fi
            done
            echo ""
            echo "   ✅ All $TOOL_COUNT tool scripts validated"
          fi
          
          echo ""
          echo "🎉 Shell script syntax validation complete"

      - name: 🔧 Install ShellCheck
        run: |
          sudo apt-get update
          sudo apt-get install -y shellcheck

      - name: 🔎 Run ShellCheck on Scripts
        run: |
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "🔎 Running ShellCheck Static Analysis"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo ""
          
          # ShellCheck main scripts
          if [ -f docker-entrypoint.sh ]; then
            echo "🔍 ShellCheck: docker-entrypoint.sh"
            shellcheck -S warning docker-entrypoint.sh || true
          fi

          # ShellCheck all tools (no .sh extension)
          if [ -d "tools" ]; then
            echo ""
            echo "🔍 ShellCheck: tools/*"
            for tool in tools/status tools/health tools/fingerprint tools/bridge-line tools/gen-auth; do
              if [ -f "$tool" ]; then
                echo "  Checking $(basename $tool)..."
                shellcheck -S warning "$tool" || true
              fi
            done
          fi
          
          echo ""
          echo "✅ ShellCheck analysis complete"

      - name: 🎯 Verify Tool Extensions
        run: |
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo "📝 Verifying Tool File Extensions (NO .sh)"
          echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
          echo ""

          if [ ! -d "tools" ]; then
            echo "⚠️  tools/ directory not found - skipping check"
            exit 0
          fi

          HAS_SH_EXT=0
          NO_EXT_COUNT=0

          # Check all files in tools/
          for file in tools/*; do
            [ -f "$file" ] || continue

            filename=$(basename "$file")

            # Check if it's a shell script (has shebang)
            if head -1 "$file" 2>/dev/null | grep -q "^#!/"; then
              # Tools should NOT have .sh extension
              if echo "$filename" | grep -q '\.sh$'; then
                echo "❌ Tool should NOT have .sh extension: $filename"
                HAS_SH_EXT=1
              else
                NO_EXT_COUNT=$((NO_EXT_COUNT + 1))
                echo "✅ Tool has correct format (no .sh): $filename"
              fi
            fi
          done

          echo ""
          echo "📊 Summary:"
          echo "   • Tools without .sh extension: $NO_EXT_COUNT"
          echo ""

          if [ $HAS_SH_EXT -eq 1 ]; then
            echo "❌ Some tools have .sh extension (should not have it)"
            exit 1
          elif [ $NO_EXT_COUNT -lt 4 ]; then
            echo "❌ Expected 5 tools (status, health, fingerprint, bridge-line, gen-auth)"
            exit 1
          else
            echo "✅ All tools have correct format (no .sh extension)"
          fi

      - name: 📋 Lint YAML Files
        run: |
          echo "🔧 Installing yamllint..."
          pip install yamllint
          echo "📋 Validating YAML files..."
          echo "📁 Checking templates (lenient rules)..."
          for yaml in templates/*.yml; do
            if [ -f "$yaml" ]; then
              yamllint -d "{extends: relaxed, rules: {line-length: {max: 200}, \
                trailing-spaces: disable, new-line-at-end-of-file: disable, \
                comments: disable}}" "$yaml" && echo "✅ $yaml valid" || \
                echo "⚠️ $yaml has warnings (non-blocking)"
            fi
          done
          echo "🔄 Checking other YAML files (strict rules)..."
          for yaml in .github/*.yml; do
            if [ -f "$yaml" ]; then
              yamllint -d relaxed "$yaml" || exit 1
              echo "✅ $yaml syntax valid"
            fi
          done
          if [ -d "docs" ]; then
            echo "📚 Checking docs (lenient)..."
            for yaml in docs/*.yml; do
              if [ -f "$yaml" ]; then
                yamllint -d "{extends: relaxed, rules: {line-length: {max: 200}, \
                  trailing-spaces: disable}}" "$yaml" && echo "✅ $yaml valid" || \
                  echo "⚠️ $yaml has warnings"
              fi
            done
          fi
          echo "ℹ️  Skipping workflow files validation (complex format)"

      - name: 🔖 Validate JSON Files
        run: |
          echo "🔍 Validating JSON files..."
          for json in templates/*.json examples/*.json .github/*.json; do
            if [ -f "$json" ]; then
              python3 -m json.tool "$json" > /dev/null || exit 1
              echo "✅ $json syntax valid"
            fi
          done

      - name: 📚 Check Documentation
        run: |
          echo "📖 Verifying required documentation files..."
          required_docs=(
            "README.md"
            "CHANGELOG.md"
            "SECURITY.md"
            "CONTRIBUTING.md"
            "CODE_OF_CONDUCT.md"
            "LICENSE.txt"
          )
          for doc in "${required_docs[@]}"; do
            if [ ! -f "$doc" ]; then
              echo "❌ Missing documentation: $doc"
              exit 1
            fi
            echo "✅ $doc exists"
          done
          if [ -d "docs" ]; then
            echo "📁 Checking docs directory..."
            for doc in ARCHITECTURE.md BACKUP.md CONTROL-PORT.md DEPLOYMENT.md FAQ.md LEGAL.md LOCAL-TESTING.md MIGRATION-V1.1.X.md MIGRATION.md MONITORING.md MULTI-MODE.md PERFORMANCE.md TOOLS.md TROUBLESHOOTING-BRIDGE-MIGRATION.md; do
              if [ -f "docs/$doc" ]; then
                echo "✅ docs/$doc exists"
              else
                echo "ℹ️  docs/$doc missing (optional)"
              fi
            done
          fi

      - name: ✅ Lint Summary
        run: echo "🎉 All linting checks passed"

  build:
    name: 🏗️ Build Docker Image
    runs-on: ubuntu-latest
    needs: lint

    steps:
      - name: 📥 Checkout Repository
        uses: actions/checkout@v5

      - name: 🖥️ Set up QEMU
        uses: docker/setup-qemu-action@v3
        with:
          platforms: arm64,amd64

      - name: 🔧 Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 🐳 Build Image (amd64 for testing)
        uses: docker/build-push-action@v6
        with:
          context: .
          file: ./Dockerfile
          platforms: linux/amd64
          load: true
          tags: tor-relay:test
          pull: true
          build-args: |
            BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')
            BUILD_VERSION=test-${{ github.run_number }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: 💾 Save Image for Testing
        run: |
          docker save tor-relay:test -o /tmp/tor-relay-test.tar
          echo "📦 Image size: $(du -h /tmp/tor-relay-test.tar | cut -f1)"

      - name: ⬆️ Upload Image Artifact
        uses: actions/upload-artifact@v5
        with:
          name: docker-image
          path: /tmp/tor-relay-test.tar
          retention-days: 1

  integration:
    name: 🧪 Integration Tests
    runs-on: ubuntu-latest
    needs: build

    steps:
      - name: 📥 Checkout Repository
        uses: actions/checkout@v5

      - name: ⬇️ Download Docker Image
        uses: actions/download-artifact@v6
        with:
          name: docker-image
          path: /tmp

      - name: 📦 Load Docker Image
        run: |
          docker load -i /tmp/tor-relay-test.tar
          docker image ls tor-relay

      - name: 🚀 Run Container Smoke Test
        run: |
          echo "🚀 Starting container for smoke test..."
          docker run -d --name tor-test --entrypoint /bin/sh tor-relay:test \
            -c "echo '✅ Container started successfully'; sleep 60" || true
          sleep 5

      - name: 🔍 Check Container Status
        run: |
          echo "📊 Container status:"
          docker ps -a | grep tor-test || true
          echo ""
          echo "📋 Container logs:"
          docker logs tor-test 2>&1 | head -30 || true

      - name: 🔧 Verify Tools Installation
        run: |
          echo "🔍 Checking installed tools..."
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "ls -la /usr/local/bin/" || exit 1
          echo ""
          echo "🛠️ Available diagnostic tools:"
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "ls -1 /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth" || exit 1

      - name: 🧅 Verify Tor Installation
        run: |
          echo "🔍 Checking Tor version..."
          TOR_VERSION=$(docker run --rm --entrypoint tor tor-relay:test --version | head -1)
          if [ -z "$TOR_VERSION" ]; then
            echo "❌ Tor installation failed"
            exit 1
          fi
          echo "✅ Tor installed: $TOR_VERSION"

      - name: 📁 Verify File Structure
        run: |
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            echo '📂 === Directory Structure ===' && \
            ls -la / | grep -E 'var|etc|usr' && \
            echo '' && \
            echo '🛠️ === Tools Directory ===' && \
            ls -la /usr/local/bin/ && \
            echo '' && \
            echo '💾 === Data Directory ===' && \
            ls -la /var/lib/tor 2>/dev/null || echo '(data dir empty, expected)' && \
            echo '' && \
            echo '📝 === Log Directory ===' && \
            ls -la /var/log/tor 2>/dev/null || echo '(log dir empty, expected)'
          "

      - name: 📋 Check Build Metadata
        run: |
          echo "🔍 Checking build metadata..."
          docker run --rm --entrypoint cat tor-relay:test /build-info.txt || exit 1

      - name: 🔐 Verify Permissions
        run: |
          echo "🔐 Verifying directory permissions..."
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            DATA_OWNER=\$(stat -c '%u %g' /var/lib/tor)
            if [ \"\$DATA_OWNER\" = '100 101' ]; then
              echo '✅ /var/lib/tor ownership correct (100:101)'
            else
              echo '❌ /var/lib/tor ownership incorrect: \$DATA_OWNER'
              exit 1
            fi

            LOG_OWNER=\$(stat -c '%u %g' /var/log/tor)
            if [ \"\$LOG_OWNER\" = '100 101' ]; then
              echo '✅ /var/log/tor ownership correct (100:101)'
            else
              echo '❌ /var/log/tor ownership incorrect: \$LOG_OWNER'
              exit 1
            fi
          "

      - name: ✅ Integration Tests Summary
        run: echo "🎉 Integration tests completed successfully"

      - name: 🧹 Cleanup
        if: always()
        run: |
          docker stop tor-test 2>/dev/null || true
          docker rm tor-test 2>/dev/null || true

  security:
    name: 🛡️ Security Scan
    runs-on: ubuntu-latest
    needs: build
    permissions:
      contents: read
      security-events: write
      actions: read

    steps:
      - name: 📥 Checkout Repository
        uses: actions/checkout@v5

      - name: ⬇️ Download Docker Image
        uses: actions/download-artifact@v6
        with:
          name: docker-image
          path: /tmp

      - name: 📦 Load Docker Image
        run: docker load -i /tmp/tor-relay-test.tar

      - name: 🔒 Trivy - Comprehensive Vulnerability Scan
        uses: aquasecurity/trivy-action@0.33.1
        with:
          image-ref: 'tor-relay:test'
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH,MEDIUM'
          vuln-type: 'os,library'
          ignore-unfixed: false
          scanners: 'vuln,secret,config'

      - name: ⬆️ Upload Trivy Results to GitHub Security
        id: upload-sarif
        uses: github/codeql-action/upload-sarif@v4
        with:
          sarif_file: 'trivy-results.sarif'
        continue-on-error: true

      - name: 📝 SARIF Upload Status
        if: always()
        run: |
          if [ "${{ steps.upload-sarif.outcome }}" = "success" ]; then
            echo "✅ SARIF results successfully uploaded to GitHub Security tab"
            echo "   View at: ${{ github.server_url }}/${{ github.repository }}/security/code-scanning"
          else
            echo "⚠️  SARIF upload skipped or failed (this is non-blocking)"
            echo ""
            echo "Possible reasons:"
            echo "  • Private repository without GitHub Advanced Security"
            echo "  • Insufficient permissions"
            echo "  • GitHub API rate limiting"
            echo ""
            echo "Security scan results are still available in:"
            echo "  ✅ Human-readable table output (see steps below)"
            echo "  ✅ JSON artifact (trivy-security-report)"
          fi

      - name: 📊 Trivy - Human Readable Report (Critical & High)
        uses: aquasecurity/trivy-action@0.33.1
        with:
          image-ref: 'tor-relay:test'
          format: 'table'
          severity: 'CRITICAL,HIGH'
          vuln-type: 'os,library'
          ignore-unfixed: false

      - name: 🔍 Trivy - Full Vulnerability List (All Severities)
        uses: aquasecurity/trivy-action@0.33.1
        with:
          image-ref: 'tor-relay:test'
          format: 'json'
          output: 'trivy-full-report.json'
          severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
          vuln-type: 'os,library'
        continue-on-error: true

      - name: 🔐 Trivy - Secret Scanning
        uses: aquasecurity/trivy-action@0.33.1
        with:
          image-ref: 'tor-relay:test'
          scanners: 'secret'
          format: 'table'
        continue-on-error: true

      - name: ⚙️ Trivy - Configuration Audit
        uses: aquasecurity/trivy-action@0.33.1
        with:
          image-ref: 'tor-relay:test'
          scanners: 'config'
          format: 'table'
        continue-on-error: true

      - name: 🗂️ Trivy - Filesystem Scan
        uses: aquasecurity/trivy-action@0.33.1
        with:
          scan-type: 'fs'
          scan-ref: '.'
          format: 'table'
          severity: 'CRITICAL,HIGH'
          scanners: 'vuln,secret,config,license'
          skip-dirs: '.git,docs,examples,templates'
        continue-on-error: true

      - name: ⬆️ Upload Full Report Artifact
        uses: actions/upload-artifact@v5
        with:
          name: trivy-security-report
          path: trivy-full-report.json
          retention-days: 7
        continue-on-error: true

      - name: 📋 Generate Security Summary
        run: |
          echo "## 🛡️ Security Scan Results" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Scans Performed:" >> $GITHUB_STEP_SUMMARY
          echo "- ✅ Image vulnerability scan (OS packages & libraries)" >> $GITHUB_STEP_SUMMARY
          echo "- ✅ Secret scanning (API keys, tokens, credentials)" >> $GITHUB_STEP_SUMMARY
          echo "- ✅ Configuration audit (Dockerfile, security best practices)" >> $GITHUB_STEP_SUMMARY
          echo "- ✅ Filesystem scan (source code vulnerabilities)" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Report Locations:" >> $GITHUB_STEP_SUMMARY
          echo "- **GitHub Security Tab:** Detailed SARIF results uploaded" >> $GITHUB_STEP_SUMMARY
          echo "- **Artifacts:** Full JSON report available for download" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "### Scan Coverage:" >> $GITHUB_STEP_SUMMARY
          echo "- **Severity Levels:** CRITICAL, HIGH, MEDIUM, LOW" >> $GITHUB_STEP_SUMMARY
          echo "- **Scan Types:** Vulnerabilities, Secrets, Configs, Licenses" >> $GITHUB_STEP_SUMMARY
          echo "- **Databases:** Alpine, NVD, GitHub Advisory" >> $GITHUB_STEP_SUMMARY

      - name: ✅ Security Scan Complete
        run: echo "🎉 Security scan completed - check GitHub Security tab for detailed results"

  test-matrix:
    name: 🧪 Test Matrix
    runs-on: ubuntu-latest
    needs: build

    strategy:
      fail-fast: false
      matrix:
        test-case:
          - 'help-flags'
          - 'file-permissions'
          - 'alpine-compatibility'
          - 'tool-executability'

    steps:
      - name: 📥 Checkout Repository
        uses: actions/checkout@v5

      - name: ⬇️ Download Docker Image
        uses: actions/download-artifact@v6
        with:
          name: docker-image
          path: /tmp

      - name: 📦 Load Docker Image
        run: docker load -i /tmp/tor-relay-test.tar

      - name: "🔍 Test: Help Flags"
        if: matrix.test-case == 'help-flags'
        run: |
          echo "🧪 Testing tool existence..."
          for tool in status health fingerprint bridge-line; do
            TOOL_PATH="/usr/local/bin/$tool"
            if docker run --rm --entrypoint /bin/sh tor-relay:test -c "test -f $TOOL_PATH"; then
              echo "✅ $tool exists at $TOOL_PATH"
            else
              echo "❌ $tool not found at $TOOL_PATH"
              exit 1
            fi
          done

      - name: "🔐 Test: File Permissions"
        if: matrix.test-case == 'file-permissions'
        run: |
          echo "🔐 Verifying file permissions for tools..."
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth; do
              if [ -f \"\$tool\" ]; then
                test -x \"\$tool\" && echo \"✅ \$(basename \$tool) is executable\" || exit 1
              fi
            done
          "
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            test -x /usr/local/bin/docker-entrypoint.sh && \
              echo '✅ docker-entrypoint.sh is executable' || exit 1
          "

      - name: "🏔️ Test: Alpine Compatibility"
        if: matrix.test-case == 'alpine-compatibility'
        run: |
          echo "🏔️ Verifying Alpine base image..."
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            cat /etc/os-release | grep -i alpine && \
              echo '✅ Alpine base confirmed' || exit 1
            test -x /bin/sh && echo '✅ /bin/sh available' || exit 1
            apk --version > /dev/null 2>&1 && echo '✅ apk available' || exit 1
            command -v tor > /dev/null 2>&1 && echo '✅ tor available' || exit 1
          "

      - name: "🔧 Test: Tool Executability"
        if: matrix.test-case == 'tool-executability'
        run: |
          echo "🔧 Testing tool execution..."
          docker run --rm --entrypoint /bin/sh tor-relay:test -c "
            for tool in /usr/local/bin/status /usr/local/bin/health /usr/local/bin/fingerprint /usr/local/bin/bridge-line /usr/local/bin/gen-auth; do
              if [ -f \"\$tool\" ]; then
                BASENAME=\$(basename \"\$tool\")
                echo \"🔍 Testing \$BASENAME...\"
                # Tools require Tor to be running, just verify they're executable
                test -x \"\$tool\" && echo \"  ✅ \$BASENAME is executable\" || exit 1
              fi
            done
          "

  summary:
    name: 📊 Build Summary
    runs-on: ubuntu-latest
    needs: [lint, build, integration, security, test-matrix]
    if: always()

    steps:
      - name: 📋 Generate Build Summary
        run: |
          cat >> $GITHUB_STEP_SUMMARY << EOF
          # 🧅 Build and Validation Pipeline

          ## 📊 Pipeline Status
          - **🔍 Lint:** \`${{ needs.lint.result }}\`
          - **🏗️ Build:** \`${{ needs.build.result }}\`
          - **🧪 Integration:** \`${{ needs.integration.result }}\`
          - **🛡️ Security:** \`${{ needs.security.result }}\`
          - **🧪 Test Matrix:** \`${{ needs.test-matrix.result }}\`

          ## 📦 Build Information
          - **🌿 Branch:** \`${{ github.ref }}\`
          - **📝 Commit:** \`${{ github.sha }}\`
          - **🔢 Run Number:** \`${{ github.run_number }}\`
          - **📅 Date:** \`$(date -u +'%Y-%m-%dT%H:%M:%SZ')\`

          ## ✅ Checks Performed
          - 🐳 Dockerfile validation with Hadolint
          - 📝 Shell script syntax checking (POSIX sh)
          - 🎯 Tool extension verification (no .sh)
          - 🔎 ShellCheck static analysis
          - 📋 YAML validation (lenient for templates)
          - 🔖 JSON validation
          - 📚 Documentation verification
          - 🏗️ Docker image build (multi-arch ready)
          - 🚀 Container smoke test
          - 🧅 Tor installation verification
          - 🔧 Tool availability check (status, health, fingerprint, bridge-line, gen-auth)
          - 🔐 Permission verification
          - 🛡️ Security scanning with Trivy
          - 🧪 Test matrix execution

          ## 🚀 Next Steps
          If all checks pass:
          - ✅ Image is ready for production use
          - 📦 Release workflow will handle publishing to GHCR and Docker Hub
          - 🏷️ Tag with semantic version to trigger release
          EOF

      - name: ✅ Build Pipeline Complete
        if: success()
        run: echo "🎉 All build and validation checks passed successfully"

      - name: ❌ Build Pipeline Failed
        if: failure()
        run: |
          echo "❌ Build pipeline failed - check logs above for details"
          exit 1

