# frozen_string_literal: true

module Gitlab
  module QA
    describe Component::LicenseOps do
      subject(:license_ops) { described_class.new }

      shared_context 'with license key' do
        let(:license_key) { valid_license_key }

        around do |example|
          ClimateControl.modify(EE_LICENSE: license_key) { example.run }
        end
      end

      let(:docker) { instance_double(Gitlab::QA::Docker::Engine) }
      let(:gitlab) do
        instance_double(
          Gitlab::QA::Component::Gitlab,
          address: "http://gitlab.example.com",
          class: Struct.new(:name).new("Gitlab::QA::Component::Gitlab")
        )
      end

      let(:valid_license_key) { 'valid-license-key' }

      before do
        allow(gitlab).to receive_messages(docker: docker, name: 'gitlab-container')
      end

      describe '#add_license' do
        context 'when license is valid' do
          include_context 'with license key'

          before do
            allow(docker).to receive(:exec).and_return('License applied successfully')
          end

          it 'successfully applies the license' do
            expect { license_ops.add_license(gitlab) }.not_to raise_error
          end
        end

        context 'when license application fails' do
          include_context 'with license key'

          before do
            allow(docker).to receive(:exec).and_return('Failed to apply license')
          end

          it 'raises a LicenseError' do
            expect { license_ops.add_license(gitlab) }
              .to raise_error(described_class::LicenseError, /Failed to apply license/)
          end
        end
      end

      describe '#fetch_license_key' do
        context 'when EE_LICENSE is not set' do
          include_context 'with license key'

          let(:license_key) { nil }

          it 'raises a LicenseError' do
            expect { license_ops.send(:fetch_license_key) }
              .to raise_error(described_class::LicenseError, /EE_LICENSE environment variable is not set or is empty/)
          end
        end

        context 'when EE_LICENSE is empty' do
          include_context 'with license key'

          let(:license_key) { '' }

          it 'raises a LicenseError' do
            expect { license_ops.send(:fetch_license_key) }
              .to raise_error(described_class::LicenseError, /EE_LICENSE environment variable is not set or is empty/)
          end
        end

        context 'when EE_LICENSE is set' do
          include_context 'with license key'

          it 'returns the license key' do
            expect(license_ops.send(:fetch_license_key)).to eq(valid_license_key)
          end
        end
      end

      describe '#build_license_command' do
        it 'builds the correct command string' do
          script = <<~RUBY
            key = ENV['EE_LICENSE']
            license = License.new(data: key)
            if license.save
              puts "License applied successfully"
            else
              STDERR.puts "Failed to apply license"
            end
          RUBY
          expected_command = "EE_LICENSE='test-key' gitlab-rails runner $'#{script.gsub("'", "\\\\'").gsub("\n", '\\n')}'"

          expect(license_ops.send(:build_license_command, 'test-key')).to eq(expected_command)
        end
      end

      describe '#verify_license_application' do
        context 'when license is applied successfully' do
          it 'does not raise an error' do
            expect { license_ops.send(:verify_license_application, 'License applied successfully') }
              .not_to raise_error
          end
        end

        context 'when license application fails' do
          it 'raises a LicenseError' do
            expect { license_ops.send(:verify_license_application, 'Failed to apply license') }
              .to raise_error(described_class::LicenseError, /Failed to apply license/)
          end
        end
      end
    end
  end
end
