name: Nightly Build

on:
  schedule:
    # Run every day at 2 AM UTC
    - cron: '0 2 * * *'
  workflow_dispatch:
    inputs:
      targets:
        description: 'Comma-separated list of targets to build (leave empty for all)'
        required: false
        default: ''
      skip_tests:
        description: 'Skip running tests'
        type: boolean
        required: false
        default: false
      create_prerelease:
        description: 'Create pre-release with nightly builds'
        type: boolean
        required: false
        default: false

env:
  CARGO_TERM_COLOR: always
  RUST_BACKTRACE: 1

jobs:
  # Check if we should skip nightly (no changes since last nightly)
  check-changes:
    name: Check for Changes
    runs-on: ubuntu-latest
    outputs:
      should_build: ${{ steps.changes.outputs.should_build }}
      commit_sha: ${{ steps.changes.outputs.commit_sha }}
      commit_message: ${{ steps.changes.outputs.commit_message }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Check for changes since last nightly
        id: changes
        run: |
          # Get the last nightly tag or fall back to a week ago
          LAST_NIGHTLY=$(git tag -l "nightly-*" | sort -V | tail -1)

          if [ -z "$LAST_NIGHTLY" ]; then
            # No previous nightly, check for changes in the last week
            SINCE="$(date -d '7 days ago' '+%Y-%m-%d')"
            echo "No previous nightly found, checking changes since $SINCE"
            CHANGES=$(git log --since="$SINCE" --oneline | wc -l)
          else
            echo "Last nightly: $LAST_NIGHTLY"
            CHANGES=$(git rev-list --count "$LAST_NIGHTLY"..HEAD)
          fi

          echo "Changes found: $CHANGES"

          if [ "$CHANGES" -gt 0 ] || [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "should_build=true" >> $GITHUB_OUTPUT
            echo "commit_sha=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
            echo "commit_message=$(git log -1 --pretty=format:'%s')" >> $GITHUB_OUTPUT
            echo "✅ Changes detected, will build nightly"
          else
            echo "should_build=false" >> $GITHUB_OUTPUT
            echo "❌ No changes since last nightly, skipping build"
          fi

  # Validate setup
  validate:
    name: Validate Setup
    runs-on: ubuntu-latest
    needs: check-changes
    if: needs.check-changes.outputs.should_build == 'true'
    outputs:
      nushell-version: ${{ steps.version.outputs.version }}
      nightly-tag: ${{ steps.tag.outputs.tag }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: '0.107.1'

      - name: Generate nightly tag
        id: tag
        run: |
          NIGHTLY_TAG="nightly-$(date '+%Y%m%d')"
          echo "tag=$NIGHTLY_TAG" >> $GITHUB_OUTPUT
          echo "Nightly tag: $NIGHTLY_TAG"

      - name: Validate nushell version
        id: version
        run: |
          echo "Validating nushell version consistency..."
          nu scripts/check_version.nu --quiet || {
            echo "Version mismatch detected, attempting fix..."
            nu scripts/check_version.nu --fix
          }
          echo "version=0.107.1" >> $GITHUB_OUTPUT

      - name: Check upstream changes
        run: |
          echo "Checking for upstream changes..."
          nu scripts/check_upstream_changes.nu || {
            echo "⚠️ Upstream changes detected but not failing nightly build"
            echo "Consider reviewing and merging upstream changes"
          }

  # Build matrix for nightly builds
  build-nightly:
    name: Nightly Build (${{ matrix.target }})
    runs-on: ${{ matrix.os }}
    needs: [check-changes, validate]
    if: needs.check-changes.outputs.should_build == 'true'
    strategy:
      fail-fast: false
      matrix:
        include:
          # Core platforms for nightly
          - target: linux-amd64
            os: ubuntu-latest
            rust-target: x86_64-unknown-linux-gnu
            cross-compile: false
            priority: high
          - target: darwin-arm64
            os: macos-latest
            rust-target: aarch64-apple-darwin
            cross-compile: false
            priority: high
          - target: windows-amd64
            os: windows-latest
            rust-target: x86_64-pc-windows-msvc
            cross-compile: false
            priority: medium

          # Additional targets (can be disabled for faster nightly)
          - target: linux-arm64
            os: ubuntu-latest
            rust-target: aarch64-unknown-linux-gnu
            cross-compile: true
            priority: low
          - target: darwin-amd64
            os: macos-13
            rust-target: x86_64-apple-darwin
            cross-compile: false
            priority: low

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.rust-target }}

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: ${{ needs.validate.outputs.nushell-version }}

      - name: Set up cross-compilation (Linux ARM64)
        if: matrix.cross-compile && matrix.target == 'linux-arm64'
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu
          echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV
          echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

      - name: Cache Cargo dependencies
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: nightly-${{ runner.os }}-${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            nightly-${{ runner.os }}-${{ matrix.target }}-cargo-
            ${{ runner.os }}-${{ matrix.target }}-cargo-

      - name: Build nightly binaries
        run: |
          echo "Building nightly binaries for ${{ matrix.target }}..."
          if [ "${{ matrix.cross-compile }}" = "true" ]; then
            nu scripts/build_cross.nu --targets ${{ matrix.target }}
          else
            nu scripts/build_all.nu --target ${{ matrix.rust-target }}
          fi
        shell: bash

      - name: Run tests
        if: github.event.inputs.skip_tests != 'true' && !matrix.cross-compile
        run: |
          echo "Running tests for ${{ matrix.target }}..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Testing $plugin..."
              cd "$plugin"
              cargo test --target ${{ matrix.rust-target }} || {
                echo "⚠️ Tests failed for $plugin but continuing nightly build"
              }
              cd ..
            fi
          done
        shell: bash

      - name: Collect nightly artifacts
        run: |
          echo "Collecting nightly artifacts..."
          nu scripts/collect_install.nu --platform ${{ matrix.target }} --force

      - name: Package nightly build
        run: |
          echo "Creating nightly package..."
          nu scripts/pack_dist.nu --platform ${{ matrix.target }} --force
        shell: bash

      - name: Upload nightly artifacts
        uses: actions/upload-artifact@v4
        with:
          name: nightly-${{ matrix.target }}
          path: |
            bin_archives/*${{ matrix.target }}*
          retention-days: 7

  # Create nightly pre-release
  create-nightly-release:
    name: Create Nightly Pre-release
    runs-on: ubuntu-latest
    needs: [check-changes, validate, build-nightly]
    if: needs.check-changes.outputs.should_build == 'true' && (github.event.inputs.create_prerelease == 'true' || github.event_name == 'schedule')
    permissions:
      contents: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: ${{ needs.validate.outputs.nushell-version }}

      - name: Download nightly artifacts
        uses: actions/download-artifact@v4
        with:
          path: nightly-artifacts/

      - name: Organize nightly assets
        run: |
          echo "Organizing nightly assets..."
          mkdir -p nightly-assets

          # Copy all archives
          find nightly-artifacts/ -name "*.tar.gz" -o -name "*.zip" | while read file; do
            # Rename to include nightly tag
            basename=$(basename "$file")
            nightly_name=$(echo "$basename" | sed "s/nushell-plugins/${{ needs.validate.outputs.nightly-tag }}-nushell-plugins/")
            cp "$file" "nightly-assets/$nightly_name"
          done

          echo "Nightly assets:"
          ls -la nightly-assets/

      - name: Generate checksums for nightly
        run: |
          cd nightly-assets
          sha256sum * > checksums.txt
          echo "Generated checksums:"
          cat checksums.txt

      - name: Delete previous nightly release
        run: |
          # Delete previous nightly release if it exists
          if gh release view "${{ needs.validate.outputs.nightly-tag }}" >/dev/null 2>&1; then
            echo "Deleting previous nightly release..."
            gh release delete "${{ needs.validate.outputs.nightly-tag }}" --yes
          fi
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        continue-on-error: true

      - name: Create nightly pre-release
        run: |
          cat > nightly_notes.md << 'EOF'
          ## Nightly Build - ${{ needs.validate.outputs.nightly-tag }}

          **⚠️ This is an automated nightly build and may be unstable.**

          ### Build Information
          - **Commit**: ${{ needs.check-changes.outputs.commit_sha }}
          - **Commit Message**: ${{ needs.check-changes.outputs.commit_message }}
          - **Build Date**: $(date -u '+%Y-%m-%d %H:%M:%S UTC')
          - **Nushell Version**: ${{ needs.validate.outputs.nushell-version }}

          ### Installation
          ```bash
          # Quick install (replace PLATFORM with your platform)
          curl -L https://github.com/${{ github.repository }}/releases/download/${{ needs.validate.outputs.nightly-tag }}/PLATFORM-${{ needs.validate.outputs.nightly-tag }}-nushell-plugins.tar.gz | tar -xz
          cd PLATFORM-${{ needs.validate.outputs.nightly-tag }}-nushell-plugins
          nu install_nu_plugins.nu
          ```

          ### Available Platforms
          $(ls nightly-assets/*.tar.gz nightly-assets/*.zip 2>/dev/null | sed 's/nightly-assets\///g' | sed 's/^/- /' || echo "- Check release assets below")

          ### Notes
          - Nightly builds are automatically created when changes are detected
          - Previous nightly builds are automatically cleaned up
          - For stable releases, see [Releases](https://github.com/${{ github.repository }}/releases)
          - Report issues with nightly builds in [Issues](https://github.com/${{ github.repository }}/issues)

          ### Verification
          All nightly assets include SHA256 checksums:
          ```bash
          sha256sum -c checksums.txt
          ```
          EOF

          gh release create "${{ needs.validate.outputs.nightly-tag }}" \
            --title "Nightly Build - ${{ needs.validate.outputs.nightly-tag }}" \
            --notes-file nightly_notes.md \
            --prerelease \
            nightly-assets/*
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Clean up old nightly releases
        run: |
          echo "Cleaning up old nightly releases (keeping last 7)..."
          gh release list --limit 50 | grep "nightly-" | tail -n +8 | while read line; do
            tag=$(echo "$line" | awk '{print $1}')
            echo "Deleting old nightly release: $tag"
            gh release delete "$tag" --yes || echo "Failed to delete $tag"
          done
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  # Notification and status
  notify:
    name: Notify Build Status
    runs-on: ubuntu-latest
    needs: [check-changes, build-nightly]
    if: always() && needs.check-changes.outputs.should_build == 'true'
    steps:
      - name: Report nightly build status
        run: |
          echo "Nightly Build Status Report"
          echo "========================="
          echo "Commit: ${{ needs.check-changes.outputs.commit_sha }}"
          echo "Message: ${{ needs.check-changes.outputs.commit_message }}"
          echo "Build Status: ${{ needs.build-nightly.result }}"

          if [ "${{ needs.build-nightly.result }}" = "success" ]; then
            echo "✅ Nightly build completed successfully"
          elif [ "${{ needs.build-nightly.result }}" = "failure" ]; then
            echo "❌ Nightly build failed"
            echo "Check the build logs for details"
          else
            echo "⚠️ Nightly build status: ${{ needs.build-nightly.result }}"
          fi

          # Could add webhook notifications here for Discord/Slack etc.

  # Maintenance tasks during nightly
  maintenance:
    name: Nightly Maintenance
    runs-on: ubuntu-latest
    needs: [check-changes, validate]
    if: needs.check-changes.outputs.should_build == 'true'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: Install Nushell
        uses: hustcer/setup-nu@v3
        with:
          version: ${{ needs.validate.outputs.nushell-version }}

      - name: Check for dependency updates
        run: |
          echo "Checking for outdated dependencies..."
          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "Checking $plugin..."
              cd "$plugin"
              cargo outdated || echo "⚠️ cargo-outdated not available"
              cd ..
            fi
          done
        continue-on-error: true

      - name: Generate dependency report
        run: |
          echo "Generating dependency report..."
          echo "# Dependency Status Report - $(date)" > dependency_report.md
          echo "" >> dependency_report.md

          for plugin in nu_plugin_*; do
            if [ -d "$plugin" ]; then
              echo "## $plugin" >> dependency_report.md
              echo "" >> dependency_report.md
              cd "$plugin"
              echo "\`\`\`" >> ../dependency_report.md
              cargo tree --depth 1 >> ../dependency_report.md || echo "Failed to generate tree" >> ../dependency_report.md
              echo "\`\`\`" >> ../dependency_report.md
              echo "" >> ../dependency_report.md
              cd ..
            fi
          done
        continue-on-error: true

      - name: Upload dependency report
        uses: actions/upload-artifact@v4
        with:
          name: nightly-dependency-report
          path: dependency_report.md
        continue-on-error: true