# frozen_string_literal: true

RSpec.describe_current do
  subject(:sampler) { described_class.new }

  context 'when we do not run system sampling and start with empty state' do
    let(:process) { sampler.to_report[:process] }
    let(:stats) { sampler.to_report[:stats] }
    let(:versions) { sampler.to_report[:versions] }

    it { expect(sampler.to_report.keys).to include(:schema_version) }
    it { expect(sampler.to_report[:type]).to eq('consumer') }
    it { expect(sampler.to_report[:dispatched_at]).not_to be_nil }
    it { expect(sampler.to_report[:jobs]).to be_empty }
    it { expect(sampler.to_report[:consumer_groups]).to be_empty }
    it { expect(process[:started_at]).not_to be_nil }
    it { expect(process[:id]).to include(Socket.gethostname) }
    it { expect(process[:status]).to eq('initialized') }
    it { expect(process[:listeners]).to eq(active: 0, standby: 0) }
    it { expect(process[:workers]).to eq(5) }
    it { expect(process[:memory_usage]).to eq(0) }
    it { expect(process[:memory_total_usage]).to eq(0) }
    it { expect(process[:memory_size]).not_to be_nil }
    it { expect(process[:cpus]).to be > 0 }
    it { expect(process[:threads]).to eq(0) }
    it { expect(process[:cpu_usage]).to eq([-1, -1, -1]) }
    it { expect(process[:tags]).to eq(Karafka::Process.tags) }
    it { expect(versions[:ruby]).to include('ruby') }
    it { expect(versions[:karafka]).to eq(Karafka::VERSION) }
    it { expect(versions[:karafka_core]).to eq(Karafka::Core::VERSION) }
    it { expect(versions[:waterdrop]).to eq(WaterDrop::VERSION) }
    it { expect(versions[:rdkafka]).to eq(Rdkafka::VERSION) }
    it { expect(versions[:librdkafka]).to eq(Rdkafka::LIBRDKAFKA_VERSION) }
    it { expect(stats[:busy]).to eq(0) }
    it { expect(stats[:enqueued]).to eq(0) }
    it { expect(stats[:utilization]).to eq(0) }
    it { expect(stats[:total][:batches]).to eq(0) }
    it { expect(stats[:total][:dead]).to eq(0) }
    it { expect(stats[:total][:errors]).to eq(0) }
    it { expect(stats[:total][:messages]).to eq(0) }
    it { expect(stats[:total][:retries]).to eq(0) }
  end

  describe '#clear' do
    before do
      sampler.track do |sampler|
        sampler.counters[:messages] += 1
        sampler.jobs[:test] = 1
        sampler.consumer_groups[:test] = 1
        sampler.errors << 1
        sampler.pauses[:test] = 1
      end

      sampler.clear
    end

    it 'expect to clear counters' do
      expect(sampler.counters[:messages]).to eq(0)
    end

    it 'expect not to clear jobs' do
      expect(sampler.jobs).not_to be_empty
    end

    it 'expect not to clear pauses' do
      expect(sampler.pauses).not_to be_empty
    end

    it 'expect not to clear consumer_groups' do
      expect(sampler.consumer_groups).not_to be_empty
    end

    it 'expect to clear errors' do
      expect(sampler.errors).to be_empty
    end
  end

  describe '#sample' do
    let(:process) { sampler.to_report[:process] }

    before { sampler.sample }

    it { expect(process[:memory_usage]).not_to eq(0) }
    it { expect(process[:memory_total_usage]).not_to eq(0) }
    it { expect(process[:threads]).not_to eq(0) }
    it { expect(process[:cpu_usage]).not_to eq([-1, -1, -1]) }
  end

  describe 'system metrics collector selection' do
    context 'when running outside container (real behavior)' do
      it 'instantiates Os metrics collector as cgroups are not available' do
        sampler = described_class.new
        # Test through public API - memory_size should work (from Os class)
        expect(sampler.to_report[:process][:memory_size]).to be > 0
      end
    end

    context 'when cgroups are available (simulated)' do
      it 'instantiates Container metrics collector' do
        allow(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Container)
          .to receive(:active?)
          .and_return(true)
        allow(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Container)
          .to receive(:new)
          .and_call_original

        described_class.new

        expect(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Container)
          .to have_received(:new)
      end
    end

    context 'when cgroups are not available (simulated)' do
      it 'instantiates Os metrics collector' do
        allow(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Container)
          .to receive(:active?)
          .and_return(false)
        allow(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Os)
          .to receive(:new)
          .and_call_original

        described_class.new

        expect(Karafka::Web::Tracking::Consumers::Sampler::Metrics::Os)
          .to have_received(:new)
      end
    end
  end
end
