#
# Simple web server that routes requests to views based on URLs.
#

require 'wunderbar/sinatra'
require 'wunderbar/bootstrap'
require 'wunderbar/vue'
require 'ruby2js/es2017/strict'
require 'ruby2js/filter/functions'
require 'ruby2js/filter/require'
require 'erb'
require 'sanitize'
require 'escape'
require 'time' # for iso8601

require_relative 'personalize'
require_relative 'helpers'
require_relative 'models/mailbox'
require_relative 'models/safetemp'
require_relative 'models/events'
require_relative 'tasks'


# monkey patch mail gem to work around a regression introduced in 2.7.0:
# https://github.com/mikel/mail/pull/1168
module Mail
  class Message
    def raw_source=(value)
      @raw_source = ::Mail::Utilities.to_crlf(value)
    end
  end

  module Utilities
    def self.safe_for_line_ending_conversion?(string)
      if RUBY_VERSION >= '1.9'
        string.ascii_only? or
          (string.encoding != Encoding::BINARY and string.valid_encoding?)
      else
        string.ascii_only?
      end
    end
  end
end

require 'whimsy/asf'
require 'whimsy/asf/memapps'
ASF::Mail.configure

SECS_TO_DAYS = 60*60*24

set :show_exceptions, true

disable :logging # suppress log of requests to stderr/error.log

# list of messages
get '/' do
  redirect to('/') if env['REQUEST_URI'] == env['SCRIPT_NAME']

  # determine latest month for which there are messages
  archives = Dir[File.join(ARCHIVE, '*.yml')].select {|name| name =~ %r{/\d{6}\.yml$}}
  @mbox = archives.empty? ? nil : File.basename(archives.sort.last, '.yml')
  if @mbox
    @mbox = [Date.today.strftime('%Y%m'), @mbox].min
    @messages = Mailbox.new(@mbox).client_headers.select do |message|
      message[:status] != :deleted
    end
  else
    @messages = [] # ensure the array exists
  end

  # Show outstanding emeritus requests
  ASF::EmeritusRequestFiles.listnames(true).each do |epoch, file|
    days = (((Time.now.to_i - epoch.to_i).to_f/SECS_TO_DAYS)).round(1)
    id = File.basename(file,'.*')
    @messages << {
      time: Time.at(epoch.to_i).gmtime.iso8601,
      href: "/roster/committer/#{id}",
      from: ASF::Person.find(id).cn,
      subject: "Pending emeritus request - #{days.to_s} days old",
      status: days < 10.0 ? :emeritusPending : :emeritusReady
    }
  end

  @cssmtime = File.mtime('public/secmail.css').to_i
  @appmtime = Wunderbar::Asset.convert(File.join(settings.views, 'app.js.rb')).mtime.to_i
  _html :index
end

# alias for root directory
get '/index.html' do
  call env.merge('PATH_INFO' => '/')
end

# support for fetching previous month's worth of messages
get %r{/(\d{6})} do |mbox|
  @mbox = mbox
  _json :index # This invokes workbench/views/index.json.rb
end

# retrieve a single message
get %r{/(\d{6})/(\w+)/} do |month, hash|
  @message = Mailbox.new(month).headers[hash]
  pass unless @message
  _html :message
end

# task lists
post '/tasklist/:file' do
  @jsmtime = File.mtime('public/tasklist.js').to_i
  @cssmtime = File.mtime('public/secmail.css').to_i

  if request.content_type == 'application/json'
    _json(:"actions/#{params[:file]}")
  else
    @dryrun = JSON.parse(_json(:"actions/#{params[:file]}"))
    _html :tasklist
  end
end

# posted actions
post '/actions/:file' do
  _json :"actions/#{params[:file]}"
end

# mark a single message as deleted
delete %r{/(\d+)/(\w+)/} do |month, hash|
  success = false

  Mailbox.update(month) do |headers|
    if headers[hash]
      headers[hash][:status] = :deleted
      success = true
    end
  end

  pass unless success
  _json success: true
end

# update a single message
patch %r{/(\d{6})/(\w+)/} do |month, hash|
  success = false

  Mailbox.update(month) do |headers|
    if headers[hash]
      updates = JSON.parse(request.env['rack.input'].read)

      # special processing for entries with symbols as keys
      headers[hash].each do |key, value|
        if Symbol === key and updates.has_key? key.to_s
          headers[hash][key] = updates.delete(key.to_s)
        end
      end

      headers[hash].merge! updates
      success = true
    end
  end

  pass unless success
  [204, {}, '']
end

# list of parts for a single message
get %r{/(\d{6})/(\w+)/_index_} do |month, hash|
  message = Mailbox.new(month).find(hash)
  pass unless message
  @attachments = message.attachments
  @headers = message.headers.dup
  @headers.delete :attachments
  @cssmtime = File.mtime('public/secmail.css').to_i
  @appmtime = Wunderbar::Asset.convert(File.join(settings.views, 'app.js.rb')).mtime.to_i
  @projects = (ASF::Podling.current+ASF::Committee.pmcs).map(&:name).sort

  # Section 4.1 of the ASF bylaws provides requirements for when membership
  # applications can be accepted.  Two days are added to cover the adjournment
  # period of the meeting during which the vote takes place.
  received = Dir["#{ASF::SVN['Meetings']}/2*/memapp-received.txt"].sort.last
  @meeting = Date.today - Date.parse(received[/\d{8}/]) <= 32 rescue true # rescue crash in local testing

  _html :parts
end

# message body for a single message
get %r{/(\d{6})/(\w+)/_body_} do |month, hash|
  @message = Mailbox.new(month).find(hash)
  @cssmtime = File.mtime('public/secmail.css').to_i
  @appmtime = Wunderbar::Asset.convert(File.join(settings.views, 'app.js.rb')).mtime.to_i
  pass unless @message
  _html :body
end

# header data for a single message
get %r{/(\d{6})/(\w+)/_headers_} do |month, hash|
  @headers = Mailbox.new(month).headers[hash]
  pass unless @headers
  _html :headers
end

# raw data for a single message
get %r{/(\d{6})/(\w+)/_raw_} do |month, hash|
  message = Mailbox.new(month).find(hash)
  pass unless message
  [200, {'Content-Type' => 'text/plain'}, message.raw]
end

# intercede for potentially dangerous message attachments
get %r{/(\d{6})/(\w+)/_danger_/(.*?)} do |month, hash, name|
  message = Mailbox.new(month).find(hash)
  pass unless message

  @part = message.find(URI.decode(name))
  pass unless @part

  _html :danger
end

# a specific attachment for a message
get %r{/(\d{6})/(\w+)/(.*?)} do |month, hash, name|
  message = Mailbox.new(month).find(hash)
  pass unless message

  part = message.find(URI.decode(name))
  pass unless part

  [200, {'Content-Type' => part.content_type}, part.body.to_s]
end

# parse memapp-received
get '/memapp.json' do
  _json :memapp
end

# return email for a given id
get '/email.json' do
  _json do
    {email: ASF::Person.find(params[:id]).mail.first}
  end
end

# return a list of iclas
get '/iclas.json' do
  list = []
  ASF::ICLA.each do |icla|
    list << {
      filename: icla.claRef,
      id: icla.id,
      name: icla.name,
      fullname: icla.legal_name,
      email: icla.email
    }
  end
  list.to_json
end

# return a list of members
get '/members.json' do
  list = []
  ASF.members.each do |member|
    list << {
        id: member.name,
        name: member.public_name
    }
  end
  _json list
end

# redirect to an icla
get %r{/icla/(.*)} do |filename|
  checkout = ASF::SVN.svnurl('iclas')
  file = ASF::ICLAFiles.match_claRef(filename)
  pass unless file
  redirect to(checkout + '/' + file)
end

# event stream for server sent events (a.k.a EventSource)
get '/events', provides: 'text/event-stream' do
  events = Events.new

  stream :keep_open do |out|
    out.callback {events.close}

    loop do
      event = events.pop

      if Hash === event or Array === event
        out << "data: #{JSON.dump(event)}\n\n"
      elsif event == :heartbeat
        out << ":\n"
      elsif event == :exit
        out.close
        break
      else
        out << "data: #{event.inspect}\n\n"
      end
    end
  end
end
