#-*- 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/>.

def init_db
  create_directory NosOignons::MEMBERS_DB_DIR
  @member_db_path = expand_path(NosOignons::MEMBERS_DB_DIR)
  ENV['NOS_OIGNONS_BOARD_WIKI_PATH'] = expand_path('.')
end

def new_member_data(name, joined_on, paid_on)
  { 'name' => name,
    'address' => "At #{name}",
    'email' => "#{name.downcase}@example.org",
    'joined_on' => joined_on,
    'membership_fee_paid_on' => paid_on
  }
end

def add_member(member_data)
  @last_member = member_data
  init_db unless @member_db_path
  file = member_filename_for_id(new_id)
  File.write file, render_member_file(@last_member)
end

def create_new_member(*args)
  add_member(new_member_data(*args))
end

Given /une base de membres vide$/ do
  init_db
end

Given /^(?:une base )?avec (\w+)(, à jour de cotisation| qui n'a pas payé sa cotisation cette année)$/ do |name, uptodate|
  # ± 15 months ago
  joined_on = (Time.now - 3600*24*30*15).strftime('%Y-%m-%d')
  case uptodate
  when ', à jour de cotisation'
    # 30 days ago
    paid_on = (Time.now - 3600*24*30).strftime('%Y-%m-%d')
  else
    paid_on = joined_on
  end
  create_new_member(name, joined_on, paid_on)
end

Given /^une base avec (\w+) qui a adhérée? le ([0-9-]+) et payé sa dernière cotisation le ([0-9-]+)$/ do |name, joined_on, paid_on|
  create_new_member(name, joined_on, paid_on)
end

Given /^une base avec (\w+), membre (\w+), ayant cotisé le ([0-9-]+)$/ do |name, member_id, paid_on|
  create_new_member(name, paid_on, paid_on)
  expect(File.read(member_filename_for_id(member_id))).to include(name)
end

Given /^une base avec (\w+), membre (\w+), n'ayant jamais cotisé$/ do |name, member_id|
  joined_on = (Time.now - 3600*24*30).strftime('%Y-%m-%d')
  create_new_member(name, joined_on, nil)
  expect(File.read(member_filename_for_id(member_id))).to include(name)
end

Given /^une base avec uniquement (\w+), membre (\w+)$/ do |name, member_id|
  paid_on = (Time.now - 3600*24*30).strftime('%Y-%m-%d')
  create_new_member(name, paid_on, paid_on)
  member_path = File.join(member_filename_for_id(member_id))
  expect(File.read(member_path)).to include(name)
  expect(Dir.glob("#{@member_db_path}/[0-9]*").size).to eq(1)
end

Given /^(?:une base )?avec (\w+) (ayant une adresse postale et |qui n'a pas d'adresse postale et )?qui doit renouveler sa cotisation d'ici (\d+) jours$/ do |name, address_status, days_before_anniversary|
  now = Time.now
  paid_on = Time.new(now.year - 1, now.month, now.day).to_date + days_before_anniversary.to_i
  joined_on = paid_on
  member_data = new_member_data(name, joined_on, paid_on)
  case address_status
  when /ayant/
    member_data['address'] = "At #{name}'s"
  when /qui n'a pas/
    member_data.delete('address')
  end
  add_member(member_data)
end

Given /^une nouvelle adhésion de (\w+)$/ do |name|
  joined_on = Time.now.strftime('%Y-%m-%d')
  create_new_member(name, joined_on, joined_on)
end

Given /^une nouvelle adhésion de (\w+) qui a payé sa cotisation il y a (\d+) jours$/ do |name, days|
  joined_on = (Time.now.to_date - days.to_i).strftime('%Y-%m-%d')
  create_new_member(name, joined_on, joined_on)
end

Given /^elle avait déjà reçu des appels l'année précédente$/ do
  Timecop.travel(Time.now.to_date - 375) do
    NosOignons::ReminderDb.instance.record(OpenStruct.new(@last_member))
  end
end

Given /^qui a déjà reçu un appel (\d+) jours plus tôt$/ do |days_ago|
  Timecop.travel(Time.now.to_date - days_ago.to_i) do
    NosOignons::ReminderDb.instance.record(OpenStruct.new(@last_member))
  end
end

Given /^qui a déjà reçu un appel le ([0-9-]+)$/ do |date|
  Timecop.travel(Time.parse(date)) do
    NosOignons::ReminderDb.instance.record(OpenStruct.new(@last_member))
  end
end

When /^j'ajoute une fiche correcte pour une nouvelle adhésion$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, render_member_file(EXTRA_MEMBER)
end

When /^j'ajoute une fiche vide$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, ''
end

When /^j'ajoute une fiche sans YAML$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    Ceci est une fiche sans YAML.
  EOF
end

When /^j'ajoute une fiche avec du mauvais YAML$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    ---
    [This is missing a closing bracket
    ---
  EOF
end

When /^j'ajoute une fiche sans email$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    ---
    name: J. Example
    address: |
      21 Jump Street
      42000 Synthé
    joined_on: 2013-02-20
    membership_fee_paid_on: 2013-02-20
    ---
  EOF
end

When /^j'ajoute une fiche sans nom$/ do
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    ---
    email: joe@example.org
    address: |
      21 Jump Street
      42000 Synthé
    joined_on: 2013-02-20
    membership_fee_paid_on: 2013-02-20
    ---
  EOF
end

When /^j'ajoute une fiche avec comme date d'adhésion "([^"]*)"$/ do |date|
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    ---
    name: J. Example
    email: joe@example.org
    address: |
      21 Jump Street
      42000 Synthé
    joined_on: #{date}
    membership_fee_paid_on: 2013-04-04
    ---
  EOF
end

When /^j'ajoute une fiche avec comme date de cotisation "([^"]*)"$/ do |date|
  @file = member_filename_for_id(new_id)
  File.write @file, <<-EOF.gsub(/^    /, '')
    ---
    name: J. Example
    email: joe@example.org
    address: |
      21 Jump Street
      42000 Synthé
    joined_on: 2013-04-04
    membership_fee_paid_on: #{date}
    ---
  EOF
end

When /^je supprime le nom sur une fiche existante$/ do
  @file = member_filename_for_id(1)
  run_command_and_stop "sed -e '/^name:/d' -i #{@file}"
end

When /^j'ajoute un fichier hors de la base des adhérents$/ do
  @file = expand_path('test')
  File.write @file, 'Test content.'
end
