#-*- 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'
  CONTACT_INFO = <<-EOT.gsub(/^    /, '')
    https://nos-oignons.net/
    contact@nos-oignons.net
    Téléphone : +33 9 72 42 96 04
    Fax : +33 9 72 42 96 06
  EOT
  POSTAL_ADDRESS = <<-EOT.gsub(/^    /, '')
    Nos oignons
    Centre UBIDOCA, 7585
    105 route des Pommiers
    74370 Saint Martin Bellevue
    France
  EOT

  # The following class methods are all meant to be called as command-line scripts
  class << self
    def create_membership_fee_receipt!(member_id, amount)
      member = NosOignons::Member.new(member_id)
      member.create_receipt!(amount)
    end

    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 email des membres à jour de cotisation'
      body = <<-END_OF_BODY.gsub(/^        /, '')
        Cher comité de déontologie de Nos oignons,

        Comme le prévoient 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
