require 'logger'

class Scheduler

  def self.logger
    @my_logger ||= ::Logger.new(File.expand_path(File.join(File.dirname(__FILE__), "..", "log", "scheduler.log")))
    @my_logger
  end

  def self.start_scheduled_builds
    logger.info("[INFO] #{Time.now} Start time scheduled builds")
    scheduling_enabled = $settings && $settings[:scheduling]
    logger.info("[INFO] #{Time.now} Scheduling enabled: #{scheduling_enabled}")

    Project.where("active = ?", true).each do |project|
      timed_enabled = project.config.scheduler_at_time rescue false
      if timed_enabled

        logger.info "[INFO][#{project.name}] #{Time.now} create a timed build: #{project.name}"

        BuildQueue.create(:project_id => project.id, :status => "pending", :category => "scheduled", :created_at => Time.now)


      end
    end

  end



  def self.start_polling_builds
    polling_enabled = $settings && $settings[:polling]
    logger.info("[INFO] #{Time.now} Polling, enabled: #{polling_enabled}")

    return if BuildRunner.busy? # skipping to next round

    scheduled_builds = BuildQueue.where("category = ? AND status = ?", "scheduled", "pending").order("created_at")
    if scheduled_builds.count > 0
      first_scheduled_build = scheduled_builds.first
      first_scheduled_build.status = 'processed'
      first_scheduled_build.updated_at = Time.now
      first_scheduled_build.save # updated

      project = first_scheduled_build.project
      next_project_build = BuildRunner.force_build(project)
      next_project_build.category = "scheduled"
      BuildRunner.build_now(next_project_build)

      return
    end

    logger.info("No previous scheduled builds found, create for each project if configured polling") if Project.where("active = ?", true).count > 0

    Project.where("active = ?", true).each do |project|
      next if project.has_pending_poll_builds?
      polling_enabled = project.config.scheduler_polling
      if polling_enabled

        outstanding_builds = BuildQueue.where("project_id = ? AND category = ? AND (status IS NULL OR status = ?)", project.id, "poll", 'pending')
        if outstanding_builds.empty?
          new_build_request = BuildQueue.create(:project_id => project.id, :category => "poll")
          new_build_request.created_at = Time.now
          new_build_request.save



          logger.info "[INFO] create a poll build: #{project.name} => #{new_build_request.id} | #{polling_enabled.inspect}"
        else
          logger.info "[INFO] there is pending already exists for the project"
        end
      end
    end

    first_build_from_queue = BuildQueue.where("status = ?", "pending").order("created_at").first
    BuildRunner.build_now(first_build_from_queue) if first_build_from_queue
  end


  def self.check_long_running_builds
    logger.info("[INFO] #{Time.now} Check for long-runningbuilds...")
    long_builds = Build.where("status = ? AND start_time < ?", "building", Time.now - 6.hour)
    if long_builds.any?
      logger.warn("[Error] Long running builds, Terminating...")
      long_builds.each do |build|
        logger.warn("#{Time.now} found long-running builds: #{build.inspect}")

        build.status = "error"
        build.save
      end
    end
  end

end