require 'reap/task'

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

class Reap::Announce < Reap::Task

  section_required true

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

  attr_accessor :title, :version, :summary, :description, :subject
  attr_accessor :to, :from, :server, :port, :domain, :account
  attr_accessor :authtype, :sectype
  attr_accessor :links, :slogan, :memo, :file

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

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

    @title       ||= master['title']
    @version     ||= master['version']
    @summary     ||= master['summary']
    @description ||= master['description']
    @links       ||= []
    @subject     ||= "[ANN] #{@title}, v#{@version}"

    @address = @to  # TODO

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

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

    # abstract
    abstract = ''
    if @description
      abstract << "\n\n"
      abstract << "ABSTRACT: #{@description}".word_wrap(72)
      abstract << "\n"
    end

    # more info
    info = ''
    unless @links.empty?
      info << "\n"
      info << "For More Information".center(67)
      info << "\n"
      @links.each{ |mi| info << "#{mi}".center(67) << "\n" }
      info << "\n"
    end

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

    # memo
    memo = ''
    if @memo
      memo = ''
      memo << "\n" << ('-' * 72) << "\n"
      memo << "(Memo)\n\n"
      memo << @memo.fold.word_wrap(72)
      #memo << "\n"
    end

    # msg file
    msg = ''
    if @file and File.file?( @file )
      msg << "\n" << ("-" * 72) << "\n"
      msg << "(from #{@file})\n\n"
      mg = ''
      File.open( @file ) { |f| mg << f.gets(nil) }
      msg << mg.fold.word_wrap(72)
    end

    # stamp
    stamp = ''
    stamp << "\n" << ("-" * 72) << "\n"
    stamp << %Q{
      |Generated by Reap, a Rake-based Ruby Project Assistant.
      |Do you Ruby?  (http://www.ruby-lang.org)
      }.margin
    stamp << "\n\n"

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

  def run
    puts "\n#{@message}\n\n"
    print "Send? [Y/n] "
    until inp = $stdin.gets[0,1] ; sleep 1 ; end
    if (inp || 'y').downcase == 'y'
      # ask for password
      print "Password for #{@account}: "
      until passwd = $stdin.gets.strip ; sleep 1 ; end
      mail = %Q{
        |From: #{@from}
        |To: #{@address}
        |Subject: #{@subject}
        |
        |#{@message}
        }.margin
      begin
        # --- Send using SMTP object and an adaptor
        Net::SMTP.enable_tls if Net::SMTP.respond_to?(:enable_tls) and @tls
        Net::SMTP.start(@server, @port, @domain, @account, passwd, @authtype) do |s|
          s.send_message mail, @from, @address
        end
        puts "Email sent successfully to #{@address}."
      rescue => e
        puts "Email delivery failed."
        puts e
      end
    else
      puts "Reap announce task canceled."
      exit 0
    end
  end

end