#-*- coding: utf-8 -*-
#
# Système de gestion des adhésions de Nos oignons
# Copyright © 2013-2014 Nos oignons <contact@nos-oignons.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

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@nos-oignons.net'
  CONTACT_INFO = <<-EOT.gsub(/^    /, '')
    Identifiant SIREN 842 479 313
    https://nos-oignons.net/
    contact@nos-oignons.net
    Téléphone : +33 9 72 42 96 04
  EOT
  POSTAL_ADDRESS = <<-EOT.gsub(/^    /, '')
    Nos oignons
    Centre UBIDOCA, 7585
    78 allée Primavera
    74370 Annecy
    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_members = NosOignons::Mailman.list_members(list)
      uptodate_emails = NosOignons::Member.all.select(&:up_to_date?).collect(&:email)

      # Who is not subscribed yet?
      emails_to_add = uptodate_emails - current_members.collect(&:email)
      emails_to_add.each do |email|
        NosOignons::Mailman.susbcribe_email(list, email)
      end

      # Who should not be subscribed anymore?
      current_members.each do |list_member|
        unless uptodate_emails.include?(list_member.email)
          list_member.unsubscribe!
        end
      end
    end

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

          $stdout.puts "Envoi d'un rappel de cotisation a #{member.to_s}"
          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

                              GNU AGPLv3 © Nos oignons <contact@nos-oignons.net>
                               git clone https://nos-oignons.net/gestion-adh.git
      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
