# require Gem::Specification.find_by_name("navi_email_sync").gem_dir+"/lib/client"
require_relative '../gmail_client'
require_relative '../client'
require 'concurrent'

module NaviEmailSync

  ##
  # This class represents the client for cloud version.
  # In cloud version, all the content will be saved and also being used from the s3
  #
  class Cloud
    include Concurrent::Async

    attr_reader :id

    def initialize(sso_web_url = ENV['api_url'], env = Rails.env)
      super()

      # client-id used to track the process
      @id = SecureRandom.uuid

      # flag to print Ruby library debug info (very detailed)
      @net_imap_debug = false

      # flag to mark email as read after gets downloaded.
      @mark_as_read = false
      # flag to turn on/off debug mode.
      @debug = false

      @logger = nil

      # sso_web (authentication) config.
      @sso_web_url = sso_web_url
      # authentication token received from sso_web used to authenticate the request to database_api
      @token = nil

      # client_type
      @client_type = "cloud"

      @download_path = config[:s3_download_folder] + '/'

      # set email_address of current_user for s3 folder name
      @current_user_email = nil
      @env = env
    end

    def override_logger(logger)
      @logger = logger
    end

    #
    # login
    #
    # login to the navi-cloud and get the authentication token
    #
    def login(session_token)
      @token = session_token
    end

    def set_current_user_email(email)
      @current_user_email = email
      @download_path = config[:s3_download_folder] + '/' + email + "/"
    end

    def set_user_details(email, identifier, method)
      @current_user_email = email
      @download_path = "#{config[:s3_download_folder]}/#{identifier}/#{method}/"
    end

    ##
    # send bulk request to navi-ai service with list of input files downloaded from imap server.
    #
    def send_request(in_filenames = [], is_last: false, email_count:)
      unless in_filenames.blank?
        filepath = @download_path + "inputs/" + (Time.now.to_f * 1000).to_s
        filename = upload_to_s3(filepath, in_filenames.join("\n"))

        HTTPService::NaviAI.start(filepath: filename, client_id: @id, client_type: @client_type, token: @token, email: @current_user_email, is_last: is_last, email_count: email_count, total_emails: @total_emails)
      end
    end

    ##
    # Downloads the email content from imap-server and save it to the download_path
    #
    def download(message, custom_uid)
      mime_type = message["mime_type"].nil? ? message.mime_type : message["mime_type"]

      if ['text/plain', 'text/html'].include? mime_type

        h = Hash.new
        out_file = @download_path + mime_type + "/"+custom_uid

        s3_filepath = upload_to_s3(out_file, encrypt(message["decoded"].nil? ? message.decoded : message["decoded"]))
        key = mime_type.split("/").join("_")

        h[key] = s3_filepath
        return h
      end
    end

    ##
    # save data to download_path with file named by filename params.
    # Input is hashmap, and it save the hashmap as yml format.
    #
    def save(data={}, filename)
      filepath = @download_path + filename + ".yml"
      return upload_to_s3(filepath, data.to_yaml)
    end

    ##
    # Helper function to upload the content to the s3
    def upload_to_s3(file_path, content)
      credentials = Aws::Credentials.new(config[:aws_key], config[:aws_secret])
      s3 = Aws::S3::Client.new(credentials: credentials, region: config[:aws_region])
      obj = s3.put_object({
                            body: content,
                            bucket: config[:s3_bucket],
                            key: file_path
                          })
      return file_path if obj.successful?
      return ""
    end

    def s3_resource_files(bucket_name, prefix)
      files = []
      credentials = Aws::Credentials.new(config[:aws_key], config[:aws_secret])
      s3 = Aws::S3::Resource.new(credentials: credentials, region: config[:aws_region])
      s3.bucket(bucket_name).objects(prefix: prefix).each do |obj|
        files << obj.key
      end
      return files
    end

    def getMessageUUIds(prefix)
      files = s3_resource_files(config[:s3_bucket], prefix)
      files.empty? ? [] : files.map { |i| i.empty? ? 0 : i.split('/').last.split("_").first }
    end

    def config
      YAML.load_file(Rails.root.join("config/navi_client.yml")).with_indifferent_access
    end
  end

  class GmailCloudApi < Cloud
    include GmailClient
  end

  class ImapCloudApi < Cloud
    include Client
  end
end