class PrintersController < ApplicationController
  # POST /devices/printers.json
  def create
    @printer = Printer.new(printer_params)
    #somewhy, Printer.validate is not run for printers created, so do corresponding things here
    prev=nil
    Printer.find( :all,
                  :attribute => 'printerDescription',
                  :value => @printer.printerDescription ).each do |pr|
      if pr.puavoServer == @printer.puavoServer
        logger.info("matching printer description #{@printer.printerDescription} at #{@printer.puavoServer}, updating")
        prev=pr
      else
        logger.warn("matching printer description, non-matching server, will create new #{@printer.printerDescription}")
      end
    end

    respond_to do |format|
      if prev
        #let's update previous entry. cups also replaces previous data if
        # a new printer is created with the same queue name
        prev.printerInfo=@printer.printerInfo
        prev.printerLocation=@printer.printerLocation
        prev.printerMakeAndModel=@printer.printerMakeAndModel
        prev.printerType=@printer.printerType
        prev.printerURI=@printer.printerURI
        if prev.save
          format.json  { render :json => prev, :status => :accepted }
        else
          format.json  { render :json => prev.errors, :status => :unprocessable_entity }
        end
      elsif @printer.save
        format.json  { render :json => @printer, :status => :created }
      else
        format.json  { render :json => @printer.errors, :status => :unprocessable_entity }
      end
    end
  end

  # GET /devices/printers
  def index
    return if redirected_nonowner_user?

    # Collect servers and group printers in them
    servers = {}

    Server.all.each do |s|
      servers[s.dn.to_s] = {
        server: s,
        hostname: s.puavoHostname,
        printers: []
      }
    end

    Printer.all.each do |p|
      next unless servers.include?(p.puavoServer.to_s)
      servers[p.puavoServer.to_s][:printers] << p
    end

    # Remove servers that have no printers
    servers.reject! { |dn, s| s[:printers].empty? }

    # Flatten and sort the servers list
    # TODO: This really needs a "natural" sort order, because
    # there can be tens of servers, usually named "bootXX"
    # where XX is an increasing number.
    @servers_and_printers = servers.values.sort do |a, b|
      a[:hostname].downcase <=>
      b[:hostname].downcase
    end

    # Finally sort the printers
    @servers_and_printers.each do |s|
      s[:printers].sort! do |a, b|
        a.printerDescription.downcase <=> b.printerDescription.downcase
      end
    end

    respond_to do |format|
      format.html # index.html.erb
    end
  end

  # GET /devices/printers/1/edit
  def edit
    return if redirected_nonowner_user?

    @printer = Printer.find(params[:id])
    @server = Server.find(@printer.puavoServer)

    @schools = School.find(
      :all,
      {
        :attribute => 'puavoPrinterQueue',
        :value => @printer.dn
      }
    )

    @schools_by_wireless = School.find(
      :all,
      {
        :attribute => 'puavoWirelessPrinterQueue',
        :value => @printer.dn
      }
    )

    @groups = Group.find(
      :all,
      {
        :attribute => 'puavoPrinterQueue',
        :value => @printer.dn
      }
    )

    @schools_by_groups = @groups.map do |group|
      [group, School.find(group.puavoSchool)]
    end

    @devices = Device.find(
      :all,
      {
        :attribute => 'puavoPrinterQueue',
        :value => @printer.dn
      }
    )

    @schools_by_devices = @devices.map do |device|
      [device, School.find(device.puavoSchool)]
    end

    respond_to do |format|
      format.html { render :action => "edit" }
    end
  end

  # PUT /devices/printers/1
  def update
    return if redirected_nonowner_user?

    @printer = Printer.find(params[:id])

    respond_to do |format|
      if @printer.update_attributes(printer_params)
        flash[:notice] = t('flash.printer.updated')
        format.html { redirect_to(printers_path) }
      else
        format.html { render :action => "edit" }
      end
    end
  end

  # DELETE /devices/printers/1
  def destroy
    return if redirected_nonowner_user?

    @printer = Printer.find(params[:id])
    @printer.destroy

    respond_to do |format|
      format.html { redirect_to(printers_url) }
    end
  end

  private
    def printer_params
      return params.require(:printer).permit(
        :printerDescription,    # used when adding a printer
        :printerInfo,
        :printerLocation,
        :printerMakeAndModel,
        :printerType,
        :printerURI,
        :puavoServer).to_hash
    end
end
