#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../config/environment.rb'
require 'optparse'
require 'optparse/time'

def pp2_deletion(imgs, titlename)
  local_tmp_path = '/home/pix/support/tmp/'
  logs_path = "/var/log/pixways/delete_images/#{Time.now.strftime("%Y%m%d")}/"

  file_name = Time.now.strftime("%Y-%m-%d-%Hh%Mm%S")+"_#{titlename}_pp2"
  main_log_file_name="#{logs_path}#{file_name}_main.log"
  main_error_log_file_name="#{logs_path}#{file_name}_main.error-log"
  pictures_list = "#{local_tmp_path}#{file_name}.txt"
  ini_file = "#{local_tmp_path}#{file_name}.ini"

  File.open(pictures_list,'wb') do |f|
    imgs.each do |i|
      f.write("#{i.to_s}\n")
    end
  end

  delete_command = "scp #{pictures_list} pix@pp2a:/tmp/; ssh pp2a 'mkdir -p #{logs_path};/var/www/pix/current/tools/delete_images /tmp/#{file_name}.txt 1>>#{main_log_file_name} 2>>#{main_error_log_file_name}';"
  delete_command += "scp #{pictures_list} pix@pp2b:/tmp/; ssh pp2b 'mkdir -p #{logs_path};/var/www/pix/current/tools/delete_images /tmp/#{file_name}.txt 1>>#{main_log_file_name} 2>>#{main_error_log_file_name}'"
  File.open(ini_file,'wb') do |f|
    f.write(delete_command)
  end

  #execute the command as a background task
  pid = Process.spawn("at -f #{ini_file} now")
  Process.detach(pid)
end

options = {}

OptionParser.new do |opts|
  opts.banner = "Usage: delete_images [options] listing.txt"

  opts.on("-f images_field", "--field", "(default file_name) name of the images table field used to find them") do |l|
    options[:field] = l
  end

  opts.on("-p provider_string_key", "--provider", String, "files will be erased only for this provider string key") do |l|
    options[:provider] = l
  end

  opts.on("-N", "--no-delete", "don't delete, just show what would be done") do |l|
    options[:no_delete] = true
  end

  opts.on("-S", "--send-PP2", "Send pictures to PP2 before deleting them") do |l|
    options[:send_PP2] = true
  end

  opts.on("-E", "--equal", "search for the exact file name") do |l|
    options[:comp] = 'E'
  end

  opts.on("-L", "--like", "search for file name containing the text provided : like '%filename%' ") do |l|
    if  options[:comp] == 'E'
      puts "error : -E and -L options can't be used together, use -h or --help for help"
      exit
    else
      options[:comp] = 'L'
    end
  end

  opts.on_tail("-h", "--help", "Show this message") do
    puts opts
    exit
  end

end.parse!

if ARGV.blank?
  puts 'error : no arguments, use -h or --help for help'
  exit
end

options[:field] = 'file_name' if options[:field].blank?
options[:comp] = 'E' if options[:comp].blank?

search_str_complement = ''
if options[:provider]
  prov = Provider.find_by_string_key(options[:provider])
  if prov.blank?
    puts "error : provider with string_key '#{options[:provider]}' does not exist"
    exit
  else
    provider_id = prov.id
    search_str_complement = " AND provider_id = #{provider_id} "
  end
end

pp2_list = []

ic = 0
ARGV.collect do |f|
  if File.zero?(f)
    puts "Pictures list file #{f} is empty !"
  elsif !File.exists?(f)
    puts "Pictures list file #{f} does not exist !"
  else
    File.open(f) do |listing|
      log_path = "/var/log/pixways/delete_images/#{Time.now.strftime('%Y%m%d')}/"
      Dir.mkdir(log_path) unless File.exists?(log_path)
      error_log = File.open("#{log_path}#{File.basename(f,".*")}.error-log","a+")
      #Open FTP connexion if send to PP2 option chosen
      if (options[:send_PP2]) and (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME)
        ftp_config = YAML.load_file(File.join(Rails.root, 'config', 'ftp.yml'))
        ftp = Net::FTP.new(ftp_config[:ms][:host],ftp_config[:ms][:temp_access][:user], ftp_config[:ms][:temp_access][:passwd])
        ftp.passive = ftp_config[:ms][:passive]
        ftp.chdir('PP2')
      end
      listing.each_line do |l|
        ic = ic + 1
        l.strip!
        if options[:comp] == 'E'
          i = Image.where("#{options[:field]} = \"#{l}\" #{search_str_complement}").first
        else
          # l_wildcard = "\"%#{l}%\""
          # i = Image.where("#{options[:field]} LIKE #{l_wildcard} #{search_str_complement}").first #utiliser .all et prévoir boucle pour les résultats multiples
          if options[:provider]
            imgs = Image.search conditions:{options[:field].to_sym=> l}, with:{provider_id: provider_id}
          else
            imgs = Image.search conditions:{options[:field].to_sym=> l}
          end
          i = imgs.first
        end
        begin
          if i.nil?
            #ToDo : chercher dans tous les sous-dossiers de /var/spool/media/ en utilisant Dir.glob("/var/spool/media/**/#{l}")
            if File.exists?("/var/spool/media/in/#{l}")
              FileUtils.rm_f("/var/spool/media/in/#{l}")
              puts ic.to_s+' '+l+' efface (/media/in)'
            elsif (Server.find_by_is_self(true).name == VINGTMINUTES_SERVER_NAME and ['SIPA','SIPAUSA','AP','REX'].include?(l.partition(".")[0]) ) or Server.find_by_is_self(true).name != VINGTMINUTES_SERVER_NAME
              error_log.write("#{l} not found\n")
            end
          else
            #Send pictures to MS in PP2 temp folder
            if (options[:send_PP2]) && (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME)
              file = "#{Rails.root}/public#{i.medium_location}"
              error_ftp = false
              # check if agency prefix is follow by one dot, if not replace by one dot
              file_name = i.file_name
              string_key = Provider.find(i.provider_id).string_key
              string_key_sep = file_name.upcase.partition(string_key.upcase)[2][0]
              file_name = string_key + '.' + file_name.upcase.partition(string_key.upcase+string_key_sep)[2] if string_key_sep!='.'
              begin
                ftp.putbinaryfile(file, file_name)
                puts "#{Time.now.to_s} : #{file_name} sent to FTP in PP2 folder"
                DELETE_LOG.info("#{Time.now.to_s} : #{file_name} sent to FTP in PP2 folder")
              rescue Exception => e
                error_log.write("#{Time.now.to_s} : error #{e} : while sending #{file_name} to FTP in PP2 folder. Image will not be deleted.\n")
                error_ftp = true
                DELETE_LOG.error("#{Time.now.to_s} : error #{e} : while sending #{file_name} to FTP in PP2 folder. Image will not be deleted.")
              end
            end
            #Destroy pictures
            if options[:no_delete]
              puts i.file_name
            else
              unless error_ftp
                begin
                  if Statistic.where(image_id: i.id).blank?
                    options[:send_PP2] && (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME) ? i.moved_to_pp2 : i.delete_hr
                    puts ic.to_s+' '+i.file_name+' efface'
                  else
                    i.deletion_for_stats(options[:send_PP2])
                    puts ic.to_s+' '+i.file_name+' stat'
                  end
                rescue Exception => e
                  error_log.write("#{Time.now.to_s} : error #{e} : while destroying #{i.file_name}\n")
                end
              end
            end
          end unless l.blank?

        rescue Exception => error
          error_log.write("#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - [ERROR] : #{error}\n")
        end

        # Deletion of Sipa_CH pictures
        begin
          if (Server.find_by_is_self(true).name == WEB_SERVER_NAME or Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME) and (['SIPA','SIPAUSA'].include?(l.partition(".")[0]))
            l_CH = 'CH_sipa.'+l.partition(".")[2]
            if options[:comp] == 'E'
              i = Image.where("#{options[:field]} = \"#{l_CH}\" #{search_str_complement}").first
            else
              # l_CH_wildcard = "\"%#{l_CH}%\""
              # i = Image.where("#{options[:field]} LIKE #{l_CH_wildcard} #{search_str_complement}").first
              if options[:provider]
                imgs = Image.search conditions:{options[:field].to_sym=> l_CH}, with:{provider_id: provider_id}
              else
                imgs = Image.search conditions:{options[:field].to_sym=> l_CH}
              end
              i = imgs.first
            end
            if i.nil?
              if File.exists?("/var/spool/media/in/#{l_CH}")
                FileUtils.rm_f("/var/spool/media/in/#{l_CH}")
                puts ic.to_s+' '+l_CH+' efface (/media/in)'
              else
                error_log.write("#{l_CH} not found\n")
              end
            else
              if options[:no_delete]
                puts i.file_name
              else
                if Statistic.where(:image_id => i.id).blank?
                  options[:send_PP2] && (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME) ? i.moved_to_pp2 : i.delete_hr
                  puts ic.to_s+' '+i.file_name+' efface'
                else
                  i.deletion_for_stats(options[:send_PP2])
                  puts ic.to_s+' '+i.file_name+' stat'
                end
              end
            end unless l.blank?
          end
        rescue Exception => error
          error_log.write("#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - [ERROR] : #{error}\n")
        end

        # Deletion of all Saif pictures on PixPalace and PixPalace2, if deletion is asked for internal pictures ("Saif" prefix)
        begin
          if ['Saif'].include?(l.partition(".")[0])
            l_publicstock = 'Saifimages.'+l.partition(".")[2] if ['Saif'].include?(l.partition(".")[0])
            if options[:comp] == 'E'
              i = Image.where("#{options[:field]} = \"#{l_publicstock}\" #{search_str_complement}").first
            else
              # l_publicstock_wildcard = "\"%#{l_publicstock}%\""
              # i = Image.where("#{options[:field]} LIKE #{l_publicstock_wildcard} #{search_str_complement}").first
              if options[:provider]
                imgs = Image.search conditions:{options[:field].to_sym=> l_publicstock}, with:{provider_id: provider_id}
              else
                imgs = Image.search conditions:{options[:field].to_sym=> l_publicstock}
              end
              i = imgs.first
            end
            pp2_list << l_publicstock if Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME
            if i.nil?
              #ToDo : chercher dans tous les sous-dossiers de /var/spool/media/ en utilisant Dir.glob("/var/spool/media/**/#{l_publicstock}")
              if File.exists?("/var/spool/media/in/#{l_publicstock}")
                FileUtils.rm_f("/var/spool/media/in/#{l_publicstock}")
                puts ic.to_s+' '+l_publicstock+' efface (/media/in)'
              elsif (Server.find_by_is_self(true).name == VINGTMINUTES_SERVER_NAME and ['SIPA','SIPAUSA','AP','REX'].include?(l.partition(".")[0]) ) or Server.find_by_is_self(true).name != VINGTMINUTES_SERVER_NAME
                error_log.write("#{l_publicstock} not found\n")
              end
            else
              if options[:no_delete]
                puts i.file_name
              else
                if Statistic.where(:image_id => i.id).blank?
                  options[:send_PP2] && (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME) ? i.moved_to_pp2 : i.delete_hr
                  puts ic.to_s+' '+i.file_name+' efface'
                else
                  i.deletion_for_stats(options[:send_PP2])
                  puts ic.to_s+' '+i.file_name+' stat'
                end
              end
            end unless l.blank?
          end
        rescue Exception => error
          error_log.write("#{Time.now.strftime("%Y-%m-%d %H:%M:%S")} - [ERROR] : #{error}\n")
        end

      end

      pp2_deletion(pp2_list, "Saifimages") unless pp2_list.blank?

      ftp.close if (options[:send_PP2]) and (Server.find_by_is_self(true).name == PIXADMIN_SERVER_NAME)
      error_log.close
      File.delete("#{log_path}#{File.basename(f,".*")}.error-log") if File.zero?("#{log_path}#{File.basename(f,".*")}.error-log")
    end
  end
end