require 'spec_helper'
require 'debci/user'
require 'debci/package'
require 'debci/storage_limit'

describe Debci::StorageLimit do
  it 'runs on the command line' do
    expect_any_instance_of(Debci::StorageLimit).to receive(:run)
    Debci::StorageLimit::CLI.new.start
  end

  let(:theuser) { Debci::User.create!(username: 'user') }
  let(:package) { Debci::Package.create!(name: "mypkg") }
  let(:ten_MB) { 10 * 1024 * 1024 }
  let(:job_data) do
    {
      requestor: theuser,
      arch: "arm64",
      suite: "unstable",
      log_size: ten_MB,
      artifacts_size: ten_MB,
    }
  end

  def create_jobs_exceeding_the_limit(package)
    now = Time.now
    [
      package.jobs.create!(date: now - 10.days, **job_data),
      package.jobs.create!(date: now -  9.days, **job_data),
      package.jobs.create!(date: now -  8.days, **job_data),
      package.jobs.create!(date: now -  7.days, **job_data),
      package.jobs.create!(date: now -  6.days, **job_data),
      package.jobs.create!(date: now -  5.days, **job_data),
      package.jobs.create!(date: now -  4.days, **job_data),
      package.jobs.create!(date: now -  3.days, **job_data),
      package.jobs.create!(date: now -  2.days, **job_data),
      package.jobs.create!(date: now -  1.days, **job_data),
      package.jobs.create!(date: now -  0.days, **job_data),
    ]
  end

  it 'removes older jobs exceeding the storage limit' do
    jobs = create_jobs_exceeding_the_limit(package)
    storage_limit = Debci::StorageLimit.new
    storage_limit.cleanup_package(package)
    jobs.each(&:reload)
    older_job = jobs.shift

    expect(older_job.files_purged).to eq(true)
    expect(jobs.map(&:files_purged).uniq).to eq([false])
  end

  it 'processes all packages exceeding the limit' do
    pkg1 = package
    pkg2 = Debci::Package.create!(name: 'otherpkg')
    pkg3 = Debci::Package.create!(name: 'yetanotherpkg')

    create_jobs_exceeding_the_limit(pkg1)
    create_jobs_exceeding_the_limit(pkg2)
    # pkg3 is under the limit
    pkg3.jobs.create!(date: Time.now - 10.days, **job_data)
    pkg3.jobs.create!(date: Time.now - 9.days, **job_data)

    storage_limit = Debci::StorageLimit.new
    expect(storage_limit).to receive(:cleanup_package).with(pkg1)
    expect(storage_limit).to receive(:cleanup_package).with(pkg2)
    expect(storage_limit).to_not receive(:cleanup_package).with(pkg3)
    storage_limit.run
  end

  it 'does not catch packages that have already been cleaned up' do
    jobs = create_jobs_exceeding_the_limit(package)
    jobs.each(&:cleanup)
    storage_limit = Debci::StorageLimit.new
    expect(storage_limit.packages_with_excess_storage).to_not include(package)
  end

  context 'with a per-package storage limit' do
    before(:each) do
      create_jobs_exceeding_the_limit(package)
      package.storage_limit = 1.gigabyte
      package.save!
    end
    let(:storage_limit) { Debci::StorageLimit.new }

    it 'respects limit when getting package list' do
      storage_limit.run
      expect(package.jobs.where(files_purged: true).count).to eq(0)
    end

    it 'respects limit when cleaning up package' do
      storage_limit.cleanup_package(package)
      expect(package.jobs.where(files_purged: true).count).to eq(0)
    end
  end

  context 'CLI' do
    before(:each) do
      create_jobs_exceeding_the_limit(package)
      package.storage_limit = 1.gigabyte
      package.save!
    end

    let(:cli) { Debci::StorageLimit::CLI.new }

    it 'lists packages' do
      expect(cli).to receive(:tp)
      cli.list
    end

    it 'cleans up package' do
      expect_any_instance_of(Debci::StorageLimit).to receive(:cleanup_package)
      cli.cleanup(package.name)
    end
  end
end
