require 'active_support/core_ext/numeric/bytes'
require 'thor'
require 'debci/package'

module Debci
  class StorageLimit
    def storage_limit
      @storage_limit ||= Debci.config.disk_storage_limit.megabytes
    end

    def packages_with_excess_storage
      expiration = Time.now - Debci.config.data_retention.days
      Debci::Package.find_by_sql("
        SELECT packages.*
        FROM packages
        JOIN jobs ON packages.id = jobs.package_id
        WHERE jobs.date > '#{expiration}' AND NOT jobs.files_purged
        GROUP BY packages.id
        HAVING sum(jobs.log_size + jobs.artifacts_size) >= #{storage_limit}
      ")
    end

    def run
      packages_with_excess_storage.each do |package|
        self.cleanup_package(package)
      end
    end

    def cleanup_package(package)
      storage = 0
      package.jobs.where(files_purged: false).order("date DESC").in_batches.each do |subset|
        subset.each do |job|
          storage += job.disk_usage
          if storage > storage_limit
            job.cleanup(reason: "package taking too much disk space")
          end
        end
      end
    end

    class CLI < Thor
      desc 'start', 'keeps storage limit by package/suite/architecture'
      def start
        ::Debci::StorageLimit.new.run
      end
      default_task :start
    end
  end
end