#-*- coding: utf-8 -*-

require 'nos_oignons/git'
require 'nos_oignons/mailman'
require 'nos_oignons/member'
require 'nos_oignons/reminder'
require 'nos_oignons/reminder_db'

module NosOignons
  BOARD_EMAIL = 'ca@nos-oignons.net'
  ADVISORS_EMAIL = 'deontologie@nos-oignons.net'
  MEMBER_MAILING_LIST = 'ag'

  # The following class methods are all meant to be called as command-line scripts
  class << self
    def list_emails!
      NosOignons::Member.all.each do |member|
        if member.up_to_date?
          puts member.email
        end
      end
    end

    def update_ag_subscribers!
      list = NosOignons::MEMBER_MAILING_LIST

      current_emails = NosOignons::Mailman.list_members(list)
      uptodate_emails = NosOignons::Member.all.select(&:up_to_date?).collect(&:email)

      emails_to_add = uptodate_emails - current_emails
      NosOignons::Mailman.add_members(list, emails_to_add) unless emails_to_add.empty?
      emails_to_remove = current_emails - uptodate_emails
      NosOignons::Mailman.remove_members(list, emails_to_remove) unless emails_to_remove.empty?
    end

    def send_membership_reminders!
      today = Time.now.to_date
      NosOignons::Member.all.select(&:up_to_date?).each do |member|
        anniversary = Time.new(today.year, member.joined_on.month,
                               member.joined_on.day).to_date
        next if member.membership_fee_paid_on >= anniversary
        next if member.reminded_on && member.reminded_on >= today
        NosOignons::Reminder.all.sort_by(&:days).reverse.each do |reminder|
          next if anniversary < today + reminder.days

          member.remind(reminder)
          break
        end
      end
    end

    def send_member_emails_to_advisors!
      uptodate_emails = NosOignons::Member.all.select(&:up_to_date?).collect(&:email)
      subject = 'Adresses emails des members à jour de cotisation'
      body = <<-END_OF_BODY.gsub(/^        /, '')
        Cher comité de déontologie de Nos oignons,

	Comme le prévoit les statuts l'article 12 des statuts de l'association,
        vous devez être en mesure de pouvoir convoquer une assemblée générale
        extraordinaire. Pour ce faire, voici donc la liste des emails à jour
        de cotisation à la date d'aujourd'hui :

        #{uptodate_emails.join("\n")}

        Et merci encore de votre engagement auprès de Nos oignons !

        -- 
        Le robot du conseil d'administration
      END_OF_BODY
      mail = Mail.new :charset => 'utf-8',
                      :from => NosOignons::BOARD_EMAIL,
                      :to => NosOignons::ADVISORS_EMAIL,
                      :subject => subject,
                      :body => body
      mail.deliver
    end

    def pre_commit_hook!
      if system('git rev-parse --quiet --verify HEAD >/dev/null')
        against = 'HEAD'
      else
        # Initial commit: diff against an empty tree object
        against = '4b825dc642cb6eb9a060e54bf8d69288fbee4904'
      end

      IO.popen(['git', 'diff-index', '--cached', '--name-status', against]) do |io|
        NosOignons::Git.handle_modified_files(io) do |file|
          next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
          begin
            # Use empty ref to get the index
            NosOignons::Member.read_from_git('', file)
          rescue ArgumentError, Psych::SyntaxError
            $stderr.puts "Désolé : #{file} n'a pas le bon format !"
            exit 1
          end
        end
      end
    end

    def pre_receive_hook!(stdin)
      stdin.readlines.each do |ref_line|
        old_value, new_value, ref_name = ref_line.rstrip.split(' ', 3)
        IO.popen(['git', 'diff', '--name-status', "#{old_value}..#{new_value}"]) do |io|
          NosOignons::Git.handle_modified_files(io) do |file|
            next unless file.start_with?("#{NosOignons::MEMBERS_DB_DIR}/")
            begin
              NosOignons::Member.read_from_git(new_value, file)
            rescue ArgumentError, Psych::SyntaxError
              $stderr.puts "Désolé : #{file} n'a pas le bon format !"
              exit 1
            end
          end
        end
      end
    end
  end
end
