require 'reap/task'

require 'net/smtp'
require 'facet/string/margin'
require 'facet/string/tab'
require 'facet/string/align_center'
require 'facet/string/fold'
require 'facet/string/word_wrap'

#    _                                    _____        _
#   /_\  _ _  _ _  ___ _  _ _ _  __ ___  |_   _|_ _ __| |__
#  / _ \| ' \| ' \/ _ \ || | ' \/ _/ -_)   | |/ _` (_-< / /
# /_/ \_\_||_|_||_\___/\_,_|_||_\__\___|   |_|\__,_/__/_\_\
#

# = Announcement Task

class Reap::Announce < Reap::Task

  section_required true

  task_desc "Send announcement email to ruby-talk or other address."

  task_help %{

    reap announce

    Send an announcement to a mailaing list or other email address.

      to           Email address to send announcemnt.
      from         Email address sent from.
      subject      Subject of email message.
      server       Email server to route message.
      port         Email server's port.
      domain       Email server's domain name.
      account      Email account name.
      type         Login type, either plain, cram_md5 or login.
      secure       Uses TLS security, true or false?

  }

  task_attr :ann

  #attr_accessor :title, :version, :summary, :description, :subject
  #attr_accessor :to, :from, :server, :port, :domain, :account
  #attr_accessor :type, :secure
  #attr_accessor :links, :slogan, :memo, :file

  def init
    ann.to       = (ann.to || 'ruby-talk@ruby-lang.org').to_s.strip
    ann.from     = (ann.from || master['email']).to_s.strip
    ann.server   = ann.server.to_s.strip
    ann.port     = (ann.port || 25).to_i
    ann.domain   = ann.domain.to_s.strip if ann.domain
    ann.account  = ann.account.to_s.strip
    ann.type     = (ann.type || 'plain').to_s.strip  #cram_md5 #plain #login

    raise "server is a require announce field" if ann.server.empty?
    raise "account is a require announce field" if ann.account.empty?

    ann.title       ||= master.title
    ann.version     ||= master.version || master.date
    ann.links       ||= []
    ann.subject     ||= "[ANN] #{ann.title}, v#{ann.version}"

    ann.address = ann.to  # TODO

    #raise "DOMAIN is a required field" if ann.domain.empty?
  end

  def run
    message = build_message

    puts "\n#{message}\n\n"
    print "Send? [y/N] "
    until inp = $stdin.gets[0,1] ; sleep 1 ; end

    unless inp.downcase == 'y'
      puts "Reap announce task canceled."
      exit 0
    end

    # ask for password
    print "Password for #{ann.account}: "
    until passwd = $stdin.gets.strip ; sleep 1 ; end

    mail = %Q{
      |From: #{ann.from}
      |To: #{ann.address}
      |Subject: #{ann.subject}
      |
      |#{message}
      }.margin
    begin
      # --- Send using SMTP object and an adaptor
      Net::SMTP.enable_tls if Net::SMTP.respond_to?(:enable_tls) and ann.secure # == :tls
      Net::SMTP.start(ann.server, ann.port, ann.domain, ann.account, passwd, ann.type) do |s|
        s.send_message mail, ann.from, ann.address
      end
      puts "Email sent successfully to #{ann.address}."
    rescue => e
      puts "Email delivery failed."
      puts e
    end

  end

private

  def build_message

    # header
    announce = %Q{
      |
      |A N N O U N C I N G
      |
      |#{ann.title}, v#{ann.version}
      |
      |#{ann.summary}
      |
      |#{ann.homepage}
      }.margin.align_center(66)

    # abstract
    abstract = ''
    if ann.description
      abstract << "\n\n"
      abstract << "ABSTRACT\n------------->\n\n#{ann.description}"
      abstract << "\n"
    end

    # more info
    info = ''
    unless ann.links.empty?
      info << "\n\n"
      info << "\nRELATED LINKS\n------------------>\n\n" #.center(67)
      ann.links.each{ |mi| info << "#{mi}" << "\n" } #.center(67) << "\n" }
      info << "\n"
    end

    # slogan
    slogan = ''
    if ann.slogan
      slogan << "\n\n"
      slogan << ann.slogan.center(67)
      slogan << "\n\n"
    end

    # memo
    memo = ''
    if ann.memo
      memo = ''
      #memo << "\n---\n" #<< ('-' * 72) << "\n"
      memo << "\nRELEASE MEMO\n----------------->\n\n"
      memo << ann.memo.strip.fold(true) #.word_wrap(67)
      #memo << "\n"
    end

    # msg file
    msg = ''
    if ann.file and File.file?( ann.file )
      msg << "\nRELEASE MEMO\n----------------->\n\n"
      #msg << "\n---\n" #<< ("-" * 68) << "\n"
      #msg << "(from #{ann.file})\n\n"
      mg = File.read( ann.file )
      msg << mg.strip.fold(true) #.word_wrap(67)
    end

    # stamp
    stamp = "\n\n\n"
    #stamp << "\n\n---\n" #<< ("-" * 68) << "\n"
    stamp << %Q{
      |               Generated by
      |
      |     o)o)o)    o)o)o)o)    o)o)    o)o)o)
      |    o)    o)  o)        o)    o)  o)    o)
      |   o)o)o)    o)o)o)    o)o)o)o)  o)o)o)
      |  o)    o)  o)        o)    o)  o)
      | o)    o)  o)o)o)o)  o)    o)  o)
      |
      |       The Ruby Project Assistant
      |
      | Do you Ruby? (http://www.ruby-lang.org)
      }.margin.indent(12)
    stamp << "\n"

    message = ''
    message << announce
    message << slogan
    message << abstract
    message << memo
    message << msg
    message << info
    message << stamp

    message
  end

end