name: CI

on:
  push:
  pull_request:
  workflow_dispatch:

jobs:
  cross-compile:
    strategy:
      fail-fast: false
      matrix:
        platform:
          - "x64-mingw32"
          - "x64-mingw-ucrt"
          - "x86_64-linux-gnu"
          - "x86_64-linux-musl"
          - "aarch64-linux-gnu"
          - "aarch64-linux-musl"

    name: cross-compile
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: "2.7"

      - name: "Install dependencies"
        run: bundle install

      - name: Write used versions into file
        shell: bash
        run: bundle exec rake ports:version_file[${{ matrix.platform }}]

      - name: Cache ports
        uses: actions/cache@v4
        with:
          path: ports
          key: cross-compiled-v1-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }}
          restore-keys: |
            cross-compiled-v1-${{ matrix.platform }}-${{ hashFiles('**/.ports_versions') }}
            cross-compiled-v1-${{ matrix.platform }}-

      - name: Build gem
        shell: bash
        run: bundle exec rake gem:native:${{ matrix.platform }}

      - uses: actions/upload-artifact@v4
        with:
          name: gem-${{ matrix.platform }}
          path: pkg/*.gem

  install-windows-mingw:
    needs:
      - cross-compile
    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - "2.7"
          - "3.0"

    name: install-windows-mingw
    runs-on: windows-latest
    steps:
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-x64-mingw32

      - name: Install native gem
        shell: pwsh
        run: gem install "tiny_tds-*.gem"

      - name: Test if TinyTDS loads
        shell: pwsh
        run: |
          ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path"
          exit $LASTEXITCODE

      - name: Test if tsql wrapper works
        shell: pwsh
        run: |
          tsql-ttds -C
          exit $LASTEXITCODE

      - name: Test if defncopy wrapper works
        shell: pwsh
        run: |
          defncopy-ttds -v
          exit $LASTEXITCODE

  test-windows-mingw:
    needs:
      - cross-compile
    strategy:
      fail-fast: false
      matrix:
        force-encryption:
          - false
          - true
        mssql-version:
          - 2017
          - 2019
          - 2022
        ruby-version:
          - "2.7"
          - "3.0"

    name: test-windows-mingw
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-x64-mingw32

      - name: Install native gem and restore cross-compiled code from it
        shell: pwsh
        run: "& ./test/bin/restore-from-native-gem.ps1"
        env:
          RUBY_ARCHITECTURE: "x64-mingw32"

      - name: Setup MSSQL
        uses: rails-sqlserver/setup-mssql@v1
        with:
          components: sqlcmd,sqlengine
          version: ${{ matrix.mssql-version }}
          sa-password: c0MplicatedP@ssword
          force-encryption: ${{ matrix.force-encryption }}

      - name: Setup MSSQL database
        shell: pwsh
        run: |
          & sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-create.sql
          & sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-login.sql

      - name: Install toxiproxy-server
        shell: pwsh
        run: |
          choco install toxiproxy-server --version=2.5.0 -y
          Start-Process toxiproxy-server

      - name: Test gem
        shell: pwsh
        run: bundle exec rake test
        env:
          TOXIPROXY_HOST: "localhost"

      - name: Test Summary
        uses: test-summary/action@v2
        with:
          paths: "test/reports/TEST-*.xml"
        if: always()

  install-windows-ucrt:
    needs:
      - cross-compile
    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    name: install-windows-ucrt
    runs-on: windows-latest
    steps:
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-x64-mingw-ucrt

      - name: Install native gem
        shell: pwsh
        run: gem install "tiny_tds-*.gem"

      - name: Test if TinyTDS loads
        shell: pwsh
        run: |
          ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path"
          exit $LASTEXITCODE

      - name: Test if tsql wrapper works
        shell: pwsh
        run: |
          tsql-ttds -C
          exit $LASTEXITCODE

      - name: Test if defncopy wrapper works
        shell: pwsh
        run: |
          defncopy-ttds -v
          exit $LASTEXITCODE

  test-windows-ucrt:
    needs:
      - cross-compile
    strategy:
      fail-fast: false
      matrix:
        force-encryption:
          - false
          - true
        mssql-version:
          - 2017
          - 2019
          - 2022
        ruby-version:
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    name: test-windows-ucrt
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-x64-mingw-ucrt

      - name: Install native gem and restore cross-compiled code from it
        shell: pwsh
        run: "& ./test/bin/restore-from-native-gem.ps1"
        env:
          RUBY_ARCHITECTURE: "x64-mingw-ucrt"

      - name: Setup MSSQL
        uses: rails-sqlserver/setup-mssql@v1
        with:
          components: sqlcmd,sqlengine
          version: ${{ matrix.mssql-version }}
          sa-password: c0MplicatedP@ssword
          force-encryption: ${{ matrix.force-encryption }}

      - name: Setup MSSQL database
        shell: pwsh
        run: |
          & sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-create.sql
          & sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-login.sql

      - name: Install toxiproxy-server
        shell: pwsh
        run: |
          choco install toxiproxy-server --version=2.5.0 -y
          Start-Process toxiproxy-server

      - name: Test gem
        shell: pwsh
        run: bundle exec rake test
        env:
          TOXIPROXY_HOST: "localhost"

      - name: Test Summary
        uses: test-summary/action@v2
        with:
          paths: "test/reports/TEST-*.xml"
        if: always()

  install-windows-native:
    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          # currently fails with a dependency resolution 
          # looking for conflicting packages...
          # :: installing mingw-w64-x86_64-gcc-libs (15.1.0-8) breaks dependency 'mingw-w64-x86_64-gcc-libs=14.2.0-3' required by mingw-w64-x86_64-gcc
          # - "2.7"
          # - "3.0"
          # - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    name: install-windows-native
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Build gem
        shell: pwsh
        run: gem build tiny_tds.gemspec

      - name: Install gem
        shell: pwsh
        run: |
          $gemVersion = (Get-Content VERSION).Trim()
          gem install "tiny_tds-$gemVersion.gem"

      - name: Test if TinyTDS loads
        shell: pwsh
        run: |
          ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path"
          exit $LASTEXITCODE

      - name: Test if tsql wrapper works
        shell: pwsh
        run: |
          tsql-ttds -C
          exit $LASTEXITCODE

      - name: Test if defncopy wrapper works
        shell: pwsh
        run: |
          defncopy-ttds -v
          exit $LASTEXITCODE

  install-linux:
    needs:
      - cross-compile
    strategy:
      fail-fast: false
      matrix:
        platform:
          - "x86_64-linux-gnu"
          - "x86_64-linux-musl"
          - "aarch64-linux-gnu"
          - "aarch64-linux-musl"

        ruby-version:
          - "2.7"
          - "3.0"
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

        include:
          - platform: x86_64-linux-musl
            docker_tag: "-alpine"
            bootstrap: "apk add -U build-base &&" # required to compile bigdecimal on Ruby 2.7

          - platform: aarch64-linux-gnu
            docker_platform: "--platform=linux/arm64"

          - platform: aarch64-linux-musl
            docker_platform: "--platform=linux/arm64"
            docker_tag: "-alpine"
            bootstrap: "apk add -U build-base &&"

    name: install-linux
    runs-on: ubuntu-22.04
    steps:
      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-${{ matrix.platform }}
          path: precompiled/gems

      - name: Setup QEMU for docker
        uses: docker/setup-qemu-action@v3
        if: ${{ matrix.docker_platform }} != ''

      - run: |
          docker run --rm -v $PWD/precompiled:/precompiled -w /precompiled \
            ${{ matrix.docker_platform }} ruby:${{ matrix.ruby-version }}${{ matrix.docker_tag }} \
            sh -c "
              gem update --system 3.3.22 &&
              ${{ matrix.bootstrap }}
              gem install --no-document ./gems/tiny_tds-*.gem &&
              ruby -e \"require 'tiny_tds'; puts TinyTds::Gem.root_path\" &&
              tsql-ttds -C &&
              defncopy-ttds -v
            "

  test-linux:
    needs:
      - cross-compile
    name: test-linux
    strategy:
      fail-fast: false
      matrix:
        force-encryption:
          - false
          - true

        mssql-version:
          - 2019
          - 2022

        ruby-version:
          - "2.7"
          - "3.0"
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Download precompiled gem
        uses: actions/download-artifact@v4
        with:
          name: gem-x86_64-linux-gnu

      - name: Install native gem and restore cross-compiled code from it
        shell: pwsh
        run: "& ./test/bin/restore-from-native-gem.ps1"
        env:
          RUBY_ARCHITECTURE: "x86_64-linux-gnu"

      - name: Setup MSSQL
        uses: rails-sqlserver/setup-mssql@v1
        with:
          components: sqlcmd,sqlengine
          version: ${{ matrix.mssql-version }}
          sa-password: "c0MplicatedP@ssword"
          force-encryption: ${{ matrix.force-encryption }}

      - name: Setup MSSQL database
        run: |
          sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-create.sql
          sqlcmd -S localhost -U sa -P "c0MplicatedP@ssword" -i ./test/sql/db-login.sql

      - name: Install toxiproxy-server
        run: |
          wget -O toxiproxy-2.5.0.deb https://github.com/Shopify/toxiproxy/releases/download/v2.5.0/toxiproxy_2.5.0_linux_amd64.deb
          sudo dpkg -i toxiproxy-2.5.0.deb
          sudo toxiproxy-server &

      - name: Run tests
        run: bundle exec rake test
        env:
          TOXIPROXY_HOST: "localhost"

      - name: Test Summary
        uses: test-summary/action@v2
        with:
          paths: "test/reports/TEST-*.xml"
        if: always()

  install-linux-native:
    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - "2.7"
          - "3.0"
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    name: install-linux-native
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Install FreeTDS
        shell: bash
        run: ./test/bin/install-freetds.sh

      - name: Build gem
        shell: bash
        run: gem build tiny_tds.gemspec

      - name: Install gem
        shell: bash
        run: gem install "tiny_tds-$(cat VERSION).gem"

      - name: Test if TinyTDS loads
        shell: bash
        run: ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path"

      - name: Test if tsql wrapper works
        shell: bash
        run: tsql-ttds -C

      - name: Test if defncopy wrapper works
        shell: bash
        run: defncopy-ttds -v

  install_macos:
    strategy:
      fail-fast: false
      matrix:
        ruby-version:
          - "2.7"
          - "3.0"
          - "3.1"
          - "3.2"
          - "3.3"
          - "3.4"

    name: install-macos-m1
    runs-on: macos-14
    steps:
      - uses: actions/checkout@v4

      - name: Install FreeTDS
        run: brew install freetds
        shell: bash

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: ${{ matrix.ruby-version }}
          bundler-cache: true

      - name: Build gem
        shell: bash
        run: gem build tiny_tds.gemspec

      - name: Install gem and test if TinyTDS loads
        shell: bash
        run: |
          gemVersion=$(<VERSION tr -d '[:space:]')
          gem install "tiny_tds-$gemVersion.gem"

      - name: Test if TinyTDS loads
        shell: bash
        run: |
          ruby -e "require 'tiny_tds'; puts TinyTds::Gem.root_path"

  formatting:
    name: Code formatting
    runs-on: ubuntu-22.04
    steps:
      - uses: actions/checkout@v4

      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: "2.7"
          bundler-cache: true

      - name: Check standardrb
        shell: bash
        run: bundle exec standardrb

      # - name: Check artistic style
      #   uses: per1234/artistic-style-action@v1
      #   with:
      #     options-file-path: "astyle.conf"
      #     target-paths: "./ext/"
      #     name-patterns: |
      #       - '*.c'
      #       - '*.h'
