# frozen_string_literal: true

require 'spec_helper'

describe ReleaseTools::Prometheus::WraparoundVacuumChecks do
  before do
    enable_feature(:pdm_vacuum_check)
  end

  describe '#running?' do
    subject(:checks) { service.running? }

    let(:tables) { %i[ci_stages ci_job_artifacts] }
    let(:service) { described_class.new(tables) }
    let(:prom_query) do
      <<~QUERY.strip
        sum(rate(pg_stat_activity_autovacuum_age_in_seconds{relname=~"ci_stages \\\\(to prevent wraparound\\\\)|ci_job_artifacts \\\\(to prevent wraparound\\\\)", type="patroni-ci"}[1m]))
      QUERY
    end

    before do
      query_instance = instance_double(ReleaseTools::Prometheus::Query)
      allow(ReleaseTools::Prometheus::Query).to receive(:new).and_return(query_instance)
      allow(query_instance).to receive(:run).with(prom_query).and_return(response)
    end

    context 'when the vacuum is active' do
      let(:response) do
        {
          'status' => 'success',
          'data' => {
            'resultType' => 'vector',
            'result' => [{
              'metric' => {},
              'value' => [1_703_063_560.544, '0.9994165111111618']
            }]
          }
        }
      end

      it { is_expected.to be_truthy }

      context 'with the feature flag disabled' do
        before do
          disable_feature(:pdm_vacuum_check)
        end

        it { is_expected.to be_falsey }
      end
    end

    context 'when the vacuum is not active' do
      let(:response) do
        {
          'status' => 'success',
          'data' => {
            'resultType' => 'vector',
            'result' => []
          }
        }
      end

      it { is_expected.to be_falsey }
    end
  end

  describe '.running?' do
    subject(:checks) { described_class.running?(migrations) }

    before do
      query_instance = instance_double(ReleaseTools::Prometheus::Query)
      allow(ReleaseTools::Prometheus::Query).to receive(:new).and_return(query_instance)
      allow(query_instance).to receive(:run).and_return({ 'data' => { 'result' => [] } })
    end

    context 'when tables have the same prefix' do
      context 'with longer tables first' do
        let(:migrations) do
          [
            '20230712064637_change_fk_ci_builds_metadata_to_ci_builds.rb',
            '20230712064638_change_fk_ci_pipelines_config_to_ci_pipelines.rb'
          ]
        end

        it 'invokes the service with the correct tables' do
          expect(described_class).to receive(:new)
            .with(%w[ci_builds_metadata ci_builds ci_pipelines_config ci_pipelines])
            .and_call_original

          expect(checks).to be_falsey
        end
      end

      context 'with shorter tables first' do
        let(:migrations) do
          [
            '20230712064637_change_fk_ci_builds_to_ci_builds_metadata.rb',
            '202307120646378_change_fk_ci_pipelines_to_ci_pipelines_config.rb'
          ]
        end

        it 'invokes the service with the correct tables' do
          expect(described_class).to receive(:new)
            .with(%w[ci_builds ci_builds_metadata ci_pipelines ci_pipelines_config])
            .and_call_original

          expect(checks).to be_falsey
        end
      end
    end

    context 'when no table matches' do
      let(:migrations) do
        [
          '20230712064637_add_async_index_on_builds.rb',
          '20230712064638_validate_async_fk_on_job_artifacts.rb'
        ]
      end

      it 'invokes the service with the correct tables' do
        expect(described_class).to receive(:new)
          .with([])
          .and_call_original

        expect(checks).to be_falsey
      end
    end
  end
end
