#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/environment.rb'

options = {}
OptionParser.new do |opts|
  opts.banner = "Usage: stats_provider_transfer.rb source_provider destination_provider [options]"

  opts.on('-f date_from', '--from', String, 'Date to transfer the statistics from') do |l|
    begin
      l.to_datetime
    rescue
      puts "Error : #{l} is not a valid date'}"
      exit
    end
    options[:from] = l
  end

  opts.on('-t date_to', '--to', String, 'Date to transfer the statistics until') do |l|
    begin
      l.to_datetime
    rescue
      puts "Error : #{l} is not a valid date'}"
      exit
    end
    options[:to] = l
  end

  opts.on('-e', '--existing', 'Transfer statistic for existing picture on destination provider only') do |e|
    options[:existing] = e
  end

  opts.on('-m', '--missing', 'Transfer statistic for missing picture on destination provider only') do |e|
    options[:missing] = e
  end

  opts.on("-d", "--dryrun", "No action executed") do |d|
    options[:dryrun] = d
  end

  opts.on("-v", "--verbose", "Verbose") do |v|
    options[:verbose] = v
  end

end.parse!

if ARGV.blank?
  puts 'Error : no argument, use -h or --help for help'
  exit
elsif ARGV.size < 2
  puts 'Error : not enough arguments, 2 are required. Use -h or --help for help'
  exit
elsif ARGV.size > 2
  puts 'Error : too many arguments, 2 only are required. Use -h or --help for help'
  exit
end

src_provider_sk = ARGV[0]
dest_provider_sk = ARGV[1]
log_filename = "stats_transfer_#{src_provider_sk}_to_#{dest_provider_sk}_#{Time.now.strftime("%Y%m%d-%H%M%S")}.log"
log_file = File.open(log_filename,"a+")
src_prov = Provider.find_by(string_key: src_provider_sk)
dest_prov = Provider.find_by(string_key: dest_provider_sk)
if src_prov.blank? || dest_prov.blank?
  puts "Error : source provider #{src_provider_sk} not found" if src_prov.blank?
  puts "Error : destination provider #{dest_provider_sk} not found" if dest_prov.blank?
  exit false
end

stats_query = ''
stats_query += stats_query.blank? ? "statistics.created_at >= '#{options[:from]}'" : "and statistics.created_at >= '#{options[:from]}'" if options[:from]
stats_query += stats_query.blank? ? "statistics.created_at <= '#{options[:to]}'" : "and statistics.created_at <= '#{options[:to]}'" if options[:to]
if stats_query.blank?
  src_stats = Statistic.joins(:image).where(images: {provider_id: src_prov.id})
else
  src_stats = Statistic.joins(:image).where(images: {provider_id: src_prov.id}).where(stats_query)
end
if src_stats.blank?
  log_file.write("Warning : no statistic found for #{src_provider_sk}.\n")
else
  log_file.write("Info : #{src_stats.count} stats found for #{src_provider_sk}\n")
  src_stats.each do |s|
    src_img = Image.find(s.image_id)
    if src_img.nil?
      log_file.write("Warning : image with id #{s.image_id} from #{src_provider_sk} statistics not found in images table.\n")
    else
      dest_img = Image.find_by(original_filename: src_img.original_filename, provider_id: dest_prov)
      if dest_img.nil?
        if options[:existing].blank?
          #prefix = src_img.file_name.partition(".")[0]
          noprefix_name = src_img.file_name.partition(".")[2]
          src_thumb_location = src_img.thumb_location
          src_medium_location = src_img.medium_location
          dest_thumb_location = src_thumb_location.gsub(/\/#{src_provider_sk}/i,"\/#{dest_provider_sk}")
          dest_medium_location = src_medium_location.gsub(/\/#{src_provider_sk}/i,"\/#{dest_provider_sk}")
          dest_thumb_path = File.dirname(dest_thumb_location)
          dest_medium_path = File.dirname(dest_medium_location)
          begin
            src_img.update(provider_id: dest_prov.id, content_error: 1, file_name: "#{dest_provider_sk}.#{noprefix_name}", thumb_location: dest_thumb_location, medium_location: dest_medium_location) unless options[:dryrun]
            log_file.write("verbose : update image id: #{src_img.id} (command : src_img.update(provider_id: #{dest_prov.id}, content_error: 1, file_name: '#{dest_provider_sk}.#{noprefix_name}', thumb_location: #{dest_thumb_location}, medium_location: #{dest_medium_location}) ).\n") if options[:verbose]
            FileUtils.mkdir_p "#{Rails.root}/public/#{dest_thumb_path}" unless options[:dryrun]
            log_file.write("verbose : FileUtils.mkdir_p #{Rails.root}/public/#{dest_thumb_path}\n") if options[:verbose]
            FileUtils.mkdir_p "#{Rails.root}/public/#{dest_medium_path}" unless options[:dryrun]
            log_file.write("verbose : FileUtils.mkdir_p #{Rails.root}/public/#{dest_medium_path}\n") if options[:verbose]
            FileUtils.mv("#{Rails.root}/public/#{src_thumb_location}", "#{Rails.root}/public/#{dest_thumb_location}", force: true) unless options[:dryrun]
            log_file.write("verbose : FileUtils.mv (#{Rails.root}/public/#{src_thumb_location},#{Rails.root}/public/#{dest_thumb_location})\n") if options[:verbose]
            FileUtils.mv("#{Rails.root}/public/#{src_medium_location}", "#{Rails.root}/public/#{dest_medium_location}", force: true) unless options[:dryrun]
            log_file.write("verbose : FileUtils.mv (#{Rails.root}/public/#{src_medium_location},#{Rails.root}/public/#{dest_medium_location})\n") if options[:verbose]
          rescue => e
            log_file.write("ERROR : error while moving image with original_filename #{src_img.original_filename} of #{src_provider_sk} to #{dest_provider_sk} : #{e}\n")
          else
            log_file.write("Info : Image with original_filename '#{src_img.original_filename}' and id #{src_img.id} of #{src_provider_sk} moved to provider #{dest_provider_sk}.\n")
          end
        end
      else
        if options[:missing].blank?
          log_file.write("Info : image with original_filename #{src_img.original_filename}  and id: #{dest_img.id} already exists on provider #{dest_provider_sk} and will be use for statistic transfer.\n")
          begin
            s.update(image_id: dest_img.id) unless options[:dryrun]
            log_file.write("verbose : statistic id: #{s.id}, update image_id from #{s.image_id} to #{dest_img.id} (command : s.update(image_id: #{dest_img.id}) ).\n") if options[:verbose]
          rescue => e
            log_file.write("ERROR : error #{e} while updating statistics with new image_id #{dest_img.id}.\n")
          else
            log_file.write("Info : Statistic #{s.id} updated with image_id #{dest_img.id}.\n")
          end
        end
      end
    end
  end
end
# v1
=begin
src_stats.each do |s|
  src_img = Image.find(s.image_id)
  if src_img.nil?
    log_file.write("Warning : image with id #{s.image_id} from #{src_provider_sk} statistics not found in images table.\n")
  else
    dest_img = Image.find_by(original_filename: src_img.original_filename, provider_id: dest_prov)
    if dest_img.nil?
      log_file.write("Warning : image with original_filename #{src_img.original_filename} of #{dest_provider_sk} not found in images table. Image with original_filename #{src_img.original_filename} of #{src_provider_sk} will be move to #{dest_provider_sk}.\n")
      unless options[:dryrun]
        log_file.write("Debug : src_img.update(provider_id: #{dest_prov.id})\n")
        #src_img.update(provider_id: dest_prov.id, content_error: 1)
      end
    else
      begin
        unless options[:dryrun]
          #s.update(image_id: dest_img.id)
          log_file.write("Debug : s.update(image_id: #{dest_img.id})\n")
        end
      rescue => e
        log_file.write("ERROR : error #{e} while updating statistics with new image_id #{dest_img.id}.\n")
      else
        log_file.write("Info : Statitic #{s.id} updated with image_id #{dest_img.id}.\n")
      end
    end
  end
end
=end

log_file.close
puts "Transfer completed, log file : #{log_filename}"