require 'gmail'

# Note: This utility no longer supports IMAP connections that persist. They will be logged out after each call.
# This was due to SMOC-353, which resulted in Errno::ECONNRESET
# Even if we caught the issue, disconnected and reconnected, the issue would still be raised...

class GmailUtils

  def initialize(username, password)
    @username = username
    @password = password
  end

  def search_email(subject, how_recent)
    perform do |gmail|
      gmail.inbox.emails.each do |email|
        return true if (email.subject == subject) && sent_recently?(email, how_recent)

        cleanup_inbox(email)
      end

      return false # If it gets here, it didn't find it.
    end
  end

  def cleanup_all_inbox
    perform do |gmail|
      gmail.inbox.emails.each do |email|
        email.delete!
      end
    end
  end

  def emails
    perform { |gmail| return gmail.inbox.emails }
  end

  private

  # Connects to gmail, Performs a Block, Disconnects
  # Takes a block of the action you'd like to perform
  def perform
    begin
      retries ||= 0
      total_retries = 3

      Gmail.connect(@username, @password) do |gmail|
        begin
          yield gmail
        ensure
          # If a return is made above, gmail won't log out. This ensures it.
          gmail.logout
        end
      end
    rescue Net::IMAP::ByeResponseError, Net::IMAP::NoResponseError => e
      # Retry Logic
      retries += 1
      if retries < total_retries
        puts "WARNING: When connecting to gmail, encountered: #{e.to_s}\n\tAttempt #{retries + 1}/#{total_retries}..."
        retry
      else
        raise e
      end
    end
  end

  def sent_recently?(email, how_recent)
    past_time = Time.now.utc - (60 * 60 * how_recent)
    message_time = Time.parse(email.date).utc
    # All Timezones converted to UTC for consistency

    return message_time > past_time
  end

  def cleanup_inbox(email) # Purpose: Delete any emails after a specified period of time
    if email.subject.include? 'has sent you a message on Twitch' # Each subject will have its own send frequency
      email.delete! unless sent_recently?(email, 5) # Delete if older than 5 hours
    elsif email.subject.include? 'is now following you on Twitch'
      email.delete! unless sent_recently?(email, 240) # Delete if older than 10 days.
    elsif email.subject.include? 'just went live on Twitch'
      email.delete! unless sent_recently?(email, 15) # Delete if older than 15 hours
    elsif email.subject.include? 'Verify your Twitch email address'
      email.delete! # Delete these emails immediately. No tests currently for them
    else
      email.delete! unless sent_recently?(email, 48) # Delete all other emails if older than 2 days
    end
  end
end
