name: Test mkdlint Action

on:
  push:
    paths:
      - '.github/actions/mkdlint/**'
      - '.github/workflows/test-action.yml'
  pull_request:
    paths:
      - '.github/actions/mkdlint/**'
      - '.github/workflows/test-action.yml'
  workflow_dispatch:

permissions:
  contents: read
  security-events: write

jobs:
  # Test binary download and caching on all platforms
  test-binary-download:
    strategy:
      fail-fast: false
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
        version: [latest, '0.8.0']
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      
      - name: Test binary download
        id: test
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          version: ${{ matrix.version }}
          use-binary: true
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify outputs
        shell: bash
        run: |
          echo "Exit code: ${{ steps.test.outputs.exit-code }}"
          echo "Error count: ${{ steps.test.outputs.error-count }}"
          echo "File count: ${{ steps.test.outputs.file-count }}"
          echo "Binary path: ${{ steps.test.outputs.binary-path }}"
          echo "Cache hit: ${{ steps.test.outputs.cache-hit }}"
          
          if [ ! -f "${{ steps.test.outputs.binary-path }}" ]; then
            echo "Error: Binary not found at ${{ steps.test.outputs.binary-path }}"
            exit 1
          fi
      
      - name: Test cache hit on second run
        id: test2
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          version: ${{ matrix.version }}
          use-binary: true
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify cache was used
        shell: bash
        run: |
          echo "Cache hit on second run: ${{ steps.test2.outputs.cache-hit }}"
          # First run might not have cache, but second run should
          # (unless it's a fresh runner or different version)

  # Test cargo build fallback
  test-cargo-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
      
      - name: Test cargo build
        id: test
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          use-binary: false
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify binary was built
        run: |
          if [ ! -f "${{ steps.test.outputs.binary-path }}" ]; then
            echo "Error: Binary not found after cargo build"
            exit 1
          fi
          
          ${{ steps.test.outputs.binary-path }} --version

  # Test SARIF generation and upload
  test-sarif-upload:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create test markdown with issues
        run: |
          mkdir -p test-docs
          cat > test-docs/test.md << 'MDEOF'
          # Test Document
          
          This is a test.
          
          
          Multiple blank lines above.
          
          ## Setup
          
          Content here.
          
          ## Setup
          
          Duplicate heading.
          MDEOF
      
      - name: Run with SARIF output
        id: sarif
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-docs/'
          output-format: sarif
          sarif-file: results.sarif
          upload-sarif: true
          fail-on-error: false
      
      - name: Verify SARIF file exists
        run: |
          if [ ! -f "results.sarif" ]; then
            echo "Error: SARIF file not created"
            exit 1
          fi
          
          # Verify it's valid JSON
          jq . results.sarif > /dev/null
          
          # Show SARIF structure
          echo "SARIF file created successfully:"
          jq '.runs[0].results | length' results.sarif
      
      - name: Upload SARIF as artifact
        uses: actions/upload-artifact@v4
        with:
          name: sarif-results
          path: results.sarif

  # Test auto-fix workflow
  test-auto-fix:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create test file with fixable issues
        run: |
          mkdir -p test-fix
          cat > test-fix/fixable.md << 'MDEOF'
          #No space after hash
          
          Trailing spaces here:    
          
          Multiple trailing spaces:        
          
          - Item 1
          -  Item 2 (extra space)
          - Item 3
          MDEOF
      
      - name: Run with auto-fix
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-fix/'
          fix: true
          fail-on-error: false
          upload-sarif: false
      
      - name: Verify fixes were applied
        run: |
          cat test-fix/fixable.md
          
          # Check that heading now has space
          if ! grep -q "^# No space" test-fix/fixable.md; then
            echo "Error: Heading not fixed"
            exit 1
          fi
          
          echo "Auto-fix succeeded!"

  # Test custom configuration
  test-custom-config:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create custom config
        run: |
          mkdir -p test-config
          cat > test-config/.markdownlint.json << 'JSONEOF'
          {
            "default": true,
            "MD013": false,
            "MD033": false
          }
          JSONEOF
          
          cat > test-config/test.md << 'MDEOF'
          # Test
          
          This line is very long and would normally fail MD013 line-length rule but we disabled it in config.
          
          <div>HTML is normally not allowed but MD033 is disabled</div>
          MDEOF
      
      - name: Run with custom config
        id: config
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-config/test.md'
          config: 'test-config/.markdownlint.json'
          upload-sarif: false
          fail-on-error: true
      
      - name: Verify no errors with custom config
        run: |
          if [ "${{ steps.config.outputs.error-count }}" != "0" ]; then
            echo "Error: Custom config not respected"
            exit 1
          fi

  # Test rule disable flags
  test-disable-rules:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create test file
        run: |
          mkdir -p test-disable
          cat > test-disable/test.md << 'MDEOF'
          # Test
          
          This line is very long and exceeds the default line length limit of 80 characters which should trigger MD013.
          
          <div>This HTML should trigger MD033</div>
          MDEOF
      
      - name: Run with disabled rules
        id: disable
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-disable/'
          disable: 'MD013,MD033'
          upload-sarif: false
          fail-on-error: true
      
      - name: Verify rules were disabled
        run: |
          if [ "${{ steps.disable.outputs.error-count }}" != "0" ]; then
            echo "Error: Rules not disabled correctly"
            exit 1
          fi

  # Test ignore patterns
  test-ignore-patterns:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create test structure
        run: |
          mkdir -p test-ignore/node_modules test-ignore/src
          echo "#Bad heading" > test-ignore/node_modules/test.md
          echo "# Good heading" > test-ignore/src/test.md
      
      - name: Run with ignore patterns
        id: ignore
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-ignore/'
          ignore: '**/node_modules/**'
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify ignored files were skipped
        run: |
          echo "Errors found: ${{ steps.ignore.outputs.error-count }}"
          # node_modules/test.md should be ignored, only src/test.md should be checked

  # Test failure modes
  test-fail-on-error:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create file with errors
        run: |
          mkdir -p test-fail
          echo "#No space" > test-fail/bad.md
      
      - name: Test fail-on-error true (should fail)
        id: fail_true
        continue-on-error: true
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-fail/'
          fail-on-error: true
          upload-sarif: false
      
      - name: Verify it failed
        run: |
          if [ "${{ steps.fail_true.outcome }}" != "failure" ]; then
            echo "Error: Should have failed with fail-on-error: true"
            exit 1
          fi
      
      - name: Test fail-on-error false (should succeed)
        id: fail_false
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-fail/'
          fail-on-error: false
          upload-sarif: false
      
      - name: Verify it succeeded
        run: |
          if [ "${{ steps.fail_false.outcome }}" != "success" ]; then
            echo "Error: Should have succeeded with fail-on-error: false"
            exit 1
          fi

  # Test output formats
  test-output-formats:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create test file
        run: |
          mkdir -p test-output
          echo "#Bad" > test-output/test.md
      
      - name: Test text format
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-output/'
          output-format: text
          upload-sarif: false
          fail-on-error: false
      
      - name: Test JSON format
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-output/'
          output-format: json
          upload-sarif: false
          fail-on-error: false
      
      - name: Test SARIF format
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-output/'
          output-format: sarif
          sarif-file: test-output.sarif
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify SARIF was created
        run: |
          if [ ! -f "test-output.sarif" ]; then
            echo "Error: SARIF file not created"
            exit 1
          fi

  # Test verbose and quiet modes
  test-verbosity:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Test verbose mode
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          verbose: true
          upload-sarif: false
          fail-on-error: false
      
      - name: Test quiet mode
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          quiet: true
          upload-sarif: false
          fail-on-error: false

  # Integration test - full workflow
  integration-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create comprehensive test suite
        run: |
          mkdir -p integration-test/docs integration-test/vendor
          
          # Good markdown
          cat > integration-test/docs/good.md << 'MDEOF'
          # Good Document
          
          This is properly formatted.
          
          ## Section 1
          
          Content here.
          
          ## Section 2
          
          More content.
          MDEOF
          
          # Bad markdown (fixable)
          cat > integration-test/docs/fixable.md << 'MDEOF'
          #Bad heading
          
          Trailing spaces:    
          
          -  Extra space in list
          - Normal item
          MDEOF
          
          # Vendor (should be ignored)
          echo "#Bad" > integration-test/vendor/ignored.md
      
      - name: Create config
        run: |
          cat > integration-test/.markdownlint.json << 'JSONEOF'
          {
            "default": true,
            "MD013": { "line_length": 120 }
          }
          JSONEOF
      
      - name: Run full workflow
        id: full
        uses: ./.github/actions/mkdlint
        with:
          files: 'integration-test/'
          config: 'integration-test/.markdownlint.json'
          ignore: '**/vendor/**'
          output-format: sarif
          sarif-file: integration.sarif
          fix: true
          upload-sarif: false
          fail-on-error: false
      
      - name: Verify results
        run: |
          echo "Exit code: ${{ steps.full.outputs.exit-code }}"
          echo "Errors: ${{ steps.full.outputs.error-count }}"
          echo "Files: ${{ steps.full.outputs.file-count }}"
          
          # Verify fixes were applied
          cat integration-test/docs/fixable.md
          
          # Verify SARIF was created
          if [ ! -f "integration.sarif" ]; then
            echo "Error: SARIF not created"
            exit 1
          fi
          
          # Verify vendor was ignored
          jq '.runs[0].results[].locations[].physicalLocation.artifactLocation.uri' integration.sarif | \
            grep -q vendor && echo "Error: Vendor files not ignored" && exit 1 || true
          
          echo "Integration test passed!"

  # Test working directory parameter
  test-working-directory:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Create subdirectory structure
        run: |
          mkdir -p subdir/docs
          echo "# Test" > subdir/docs/test.md
      
      - name: Run from subdirectory
        uses: ./.github/actions/mkdlint
        with:
          files: 'docs/'
          working-directory: 'subdir'
          upload-sarif: false
          fail-on-error: false

  # Test job summary output
  test-job-summary:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Create test file with errors
        run: |
          mkdir -p test-summary
          cat > test-summary/errors.md << 'TESTEOF'
          #Bad heading
          Some text here

          ## heading

          ## heading
          TESTEOF

      - name: Run with job summary enabled
        id: summary-test
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-summary/'
          upload-sarif: false
          fail-on-error: false
          job-summary: true
          output-format: sarif

      - name: Verify new outputs exist
        run: |
          echo "Warning count: ${{ steps.summary-test.outputs.warning-count }}"
          echo "Duration ms: ${{ steps.summary-test.outputs.duration-ms }}"

          # Duration should be a number > 0
          if [ -z "${{ steps.summary-test.outputs.duration-ms }}" ]; then
            echo "Error: duration-ms output is empty"
            exit 1
          fi

          # warning-count should be set (can be 0)
          if [ -z "${{ steps.summary-test.outputs.warning-count }}" ]; then
            echo "Error: warning-count output is empty"
            exit 1
          fi

      - name: Run with job summary disabled
        uses: ./.github/actions/mkdlint
        with:
          files: 'test-summary/'
          upload-sarif: false
          fail-on-error: false
          job-summary: false

  # Test incremental linting (changed-only mode)
  test-changed-only:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Test changed-only on push (should lint all files)
        id: push-test
        uses: ./.github/actions/mkdlint
        with:
          files: 'README.md'
          changed-only: true
          upload-sarif: false
          fail-on-error: false

      - name: Verify push event lints normally
        run: |
          # On push events, changed-only should still lint the specified files
          echo "Exit code: ${{ steps.push-test.outputs.exit-code }}"

  # Summary job
  test-summary:
    runs-on: ubuntu-latest
    needs:
      - test-binary-download
      - test-cargo-build
      - test-sarif-upload
      - test-auto-fix
      - test-custom-config
      - test-disable-rules
      - test-ignore-patterns
      - test-fail-on-error
      - test-output-formats
      - test-verbosity
      - integration-test
      - test-working-directory
      - test-job-summary
      - test-changed-only
    if: always()
    steps:
      - name: Check all tests passed
        run: |
          if [ "${{ needs.test-binary-download.result }}" != "success" ] || \
             [ "${{ needs.test-cargo-build.result }}" != "success" ] || \
             [ "${{ needs.test-sarif-upload.result }}" != "success" ] || \
             [ "${{ needs.test-auto-fix.result }}" != "success" ] || \
             [ "${{ needs.test-custom-config.result }}" != "success" ] || \
             [ "${{ needs.test-disable-rules.result }}" != "success" ] || \
             [ "${{ needs.test-ignore-patterns.result }}" != "success" ] || \
             [ "${{ needs.test-fail-on-error.result }}" != "success" ] || \
             [ "${{ needs.test-output-formats.result }}" != "success" ] || \
             [ "${{ needs.test-verbosity.result }}" != "success" ] || \
             [ "${{ needs.integration-test.result }}" != "success" ] || \
             [ "${{ needs.test-working-directory.result }}" != "success" ] || \
             [ "${{ needs.test-job-summary.result }}" != "success" ] || \
             [ "${{ needs.test-changed-only.result }}" != "success" ]; then
            echo "❌ Some tests failed"
            exit 1
          else
            echo "✅ All tests passed!"
          fi
