require Gem::Specification.find_by_name("navi_client").gem_dir+"/lib/client"
require 'concurrent'

module NaviClient

  ##
  # 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
    include Client

    attr_reader :id

    def initialize(sso_web_url = "http://localhost:3008/")
      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
    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
    end

    ##
    # send bulk request to navi-ai service with list of input files downloaded from imap server.
    #
    def send_request(in_filenames = [])
      unless in_filenames.blank?
        download_path = config['s3_download_folder'] + "/" + @current_user_email
        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)
      end
    end

    ##
    # Downloads the email content from imap-server and save it to the download_path
    #
    def download(message, custom_uid)
      download_path = config[:s3_download_folder] + "/" + @current_user_email
      if ['text/plain', 'text/html'].include? message.mime_type

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

        s3_filepath = upload_to_s3(out_file, encrypt(message.decoded))
        key = message.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)
      download_path = config[:s3_download_folder] + "/" + @current_user_email
      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 config
      YAML.load_file(Rails.root.join("config/navi_client.yml")).with_indifferent_access
    end
  end
end