module ZuoraConnect::Controllers::Helpers

def authenticate_connect_app_request

def authenticate_connect_app_request
  ZuoraConnect::AppInstance.read_master_db do
    Thread.current[:appinstance] = nil
    if ZuoraConnect.logger.is_a?(Ougai::Logger); ZuoraConnect.logger.with_fields = {}; end
    if Rails.logger.is_a?(Ougai::Logger); Rails.logger.with_fields = {}; end
    if defined?(ElasticAPM) && ElasticAPM.running?
      if ElasticAPM.respond_to?(:set_label)
        ElasticAPM.set_label(:trace_id, request.uuid)
      else
        ElasticAPM.set_label(:trace_id, request.uuid)
      end
    end
    start_time = Time.now
    if ZuoraConnect.configuration.mode == "Production"
      setup_instance_via_prod_mode
    else
      setup_instance_via_dev_mode
    end
    return if performed?
    if !defined?(@appinstance) || @appinstance.blank?
      render "zuora_connect/static/error_handled", :locals => {
        :title => "Application state could not be found.",
        :message => "Please relaunch application."
      }, :layout => false
      return
    end
    #Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
    #so data lookup provides a model method that can be overriden per app.
    if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
      if @appinstance.new_session_for_ui_requests(:params => params)
        @appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
      end
    end
    if session["#{@appinstance.id}::user::email"].present?
      ElasticAPM.set_user(session["#{@appinstance.id}::user::email"])  if defined?(ElasticAPM) && ElasticAPM.running?
      PaperTrail.whodunnit =  session["#{@appinstance.id}::user::email"] if defined?(PaperTrail)
    end
    begin
      locale = session["#{@appinstance.id}::user::locale"]
      I18n.locale = locale.present? ? locale : @appinstance.locale
    rescue I18n::InvalidLocale => ex
      ZuoraConnect.logger.error(ex) if !ZuoraConnect::AppInstance::IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
    end
    begin
      Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
    rescue
      ZuoraConnect.logger.error(ex)
    end
    ZuoraConnect.logger.debug("Authenticate App Request Completed In - #{(Time.now - start_time).round(2)}s")
  end
rescue ZuoraConnect::Exceptions::InvalidCredentialSet => ex
  id = @appinstance.id
  ZuoraConnect::AppInstance.destroy(id)
  Apartment::Tenant.drop(id)
  render "zuora_connect/static/error_handled", :locals => {
    :title => "Application Setup Error",
    :message => "Application cannot be run using Zuora Session. Delete old application \
    deployment and create new with Zuora Basic or OAuth credentials."
  }, :layout => false
  return
rescue ZuoraConnect::Exceptions::AccessDenied => ex
  respond_to do |format|
    format.html {
      render "zuora_connect/static/error_handled", :locals => {
          :title => "Application State Error",
          :message => ex.message
        }, status: 401, layout: false
    }
    format.js {
      render "zuora_connect/static/error_handled", :locals => {
          :title => "Application State Error",
          :message => ex.message
        }, status: 401, layout: false
    }
    format.json { render json: {'errors' => ex.message}, status: 401 }
    format.all { render json: ex.message, status: 401 }
  end
  return
rescue => ex
  ZuoraConnect.logger.error("UI Authorization Error", ex)
  respond_to do |format|
    format.html { render 'zuora_connect/static/error_unhandled', :locals => {:exception => ex, :skip_exception => true}, status: 500, layout: false }
    format.js { render 'zuora_connect/static/error_unhandled', :locals => {:exception => ex, :skip_exception => true}, status: 500, layout: false}
  end
  return
end