<commit_before>class Api::ApplicationInstancesController < Api::ApiApplicationController

  include Concerns::CanvasSupport

  load_and_authorize_resource :application
  load_and_authorize_resource :application_instance, through: :application

  before_action :set_configs, only: [:create, :update]

  def index
    @application_instances = @application_instances.
      by_oldest.
      paginate(page: params[:page], per_page: 30)
    set_requests
    application_instances = @application_instances.map do |app_inst|
      authentications = get_authentications(app_inst)
      app_inst_json = app_inst.as_json(include: :site)
      app_inst_json["lti_config_xml"] = app_inst.lti_config_xml
      app_inst_json["canvas_token_preview"] = app_inst.canvas_token_preview
      app_inst_json["authentications"] = authentications
      app_inst_json["request_stats"] = request_stats(app_inst.tenant)
      app_inst_json.delete("encrypted_canvas_token")
      app_inst_json.delete("encrypted_canvas_token_salt")
      app_inst_json.delete("encrypted_canvas_token_iv")
      app_inst_json
    end
    render json: {
      application_instances: application_instances,
      total_pages: @application_instances.total_pages,
    }
  end

  def show
    respond_with_json
  end

  def create
    @application_instance.save!
    respond_with_json
  end

  def update
    @application_instance.update(application_instance_params)
    respond_with_json
  end

  def destroy
    tenant = @application_instance.tenant
    @application_instance.destroy
    Apartment::Tenant.drop(tenant)
    RequestStatistic.where(tenant: tenant).delete_all
    RequestUserStatistic.where(tenant: tenant).delete_all
    render json: { head: :ok }
  end

  def check_auth
    site = @application_instance.site
    url = UrlHelper.scheme_host_port(site.url)
    Apartment::Tenant.switch(@application_instance.tenant) do
      auth = @application_instance.authentications.find(params[:authentication_id])
      api = Integrations::CanvasApiSupport.refreshable_auth(auth, url, site)
      if accounts = api.proxy("LIST_ACCOUNTS", {}, {}, true)
        render json: accounts
      else
        render json: []
      end
    end
  end

  private

  def get_authentications(application_instance_instance)
    Apartment::Tenant.switch(application_instance_instance.tenant) do
      application_instance_instance.authentications.map do |authentication|
        {
          id: authentication.id,
          user: authentication.user&.display_name,
          email: authentication.user&.email,
          provider: authentication.provider,
          created_at: authentication.created_at,
        }
      end
    end
  end

  def set_configs
    # Strong params doesn't allow arbitrary json to be permitted
    # So we have to explicitly set the config
    # This will be allowed in rails 5.1
    @application_instance.config = params[:application_instance][:config]
    @application_instance.lti_config = params[:application_instance][:lti_config]
  end

  def respond_with_json
    authentications = get_authentications(@application_instance)
    application_instance = @application_instance.as_json(include: :site)
    application_instance["lti_config_xml"] = @application_instance.lti_config_xml
    application_instance["canvas_token_preview"] = @application_instance.canvas_token_preview
    application_instance.delete("encrypted_canvas_token")
    application_instance.delete("encrypted_canvas_token_salt")
    application_instance.delete("encrypted_canvas_token_iv")
    application_instance["authentications"] = authentications
    render json: application_instance
  end

  def set_requests
    tenants = @application_instances.pluck(:tenant)
    @day_1_requests_grouped, @day_7_requests_grouped, @day_30_requests_grouped =
      RequestStatistic.total_requests_grouped(tenants)<commit_msg>Refactor loading app instances Re-use code to load app instances Fixes loading single app instance to also include request stats<commit_after>class Api::ApplicationInstancesController < Api::ApiApplicationController

  include Concerns::CanvasSupport

  load_and_authorize_resource :application
  load_and_authorize_resource :application_instance, through: :application

  before_action :set_configs, only: [:create, :update]

  def index
    @application_instances = @application_instances.
      by_oldest.
      paginate(page: params[:page], per_page: 30)
    set_requests
    application_instances_json = @application_instances.map do |application_instance|
      json_for(application_instance)
    end
    render json: {
      application_instances: application_instances_json,
      total_pages: @application_instances.total_pages,
    }
  end

  def show
    respond_with_json
  end

  def create
    @application_instance.save!
    respond_with_json
  end

  def update
    @application_instance.update(application_instance_params)
    respond_with_json
  end

  def destroy
    tenant = @application_instance.tenant
    @application_instance.destroy
    Apartment::Tenant.drop(tenant)
    RequestStatistic.where(tenant: tenant).delete_all
    RequestUserStatistic.where(tenant: tenant).delete_all
    render json: { head: :ok }
  end

  def check_auth
    site = @application_instance.site
    url = UrlHelper.scheme_host_port(site.url)
    Apartment::Tenant.switch(@application_instance.tenant) do
      auth = @application_instance.authentications.find(params[:authentication_id])
      api = Integrations::CanvasApiSupport.refreshable_auth(auth, url, site)
      if accounts = api.proxy("LIST_ACCOUNTS", {}, {}, true)
        render json: accounts
      else
        render json: []
      end
    end
  end

  private

  def get_authentications(application_instance_instance)
    Apartment::Tenant.switch(application_instance_instance.tenant) do
      application_instance_instance.authentications.map do |authentication|
        {
          id: authentication.id,
          user: authentication.user&.display_name,
          email: authentication.user&.email,
          provider: authentication.provider,
          created_at: authentication.created_at,
        }
      end
    end
  end

  def set_configs
    # Strong params doesn't allow arbitrary json to be permitted
    # So we have to explicitly set the config
    # This will be allowed in rails 5.1
    @application_instance.config = params[:application_instance][:config]
    @application_instance.lti_config = params[:application_instance][:lti_config]
  end

  def respond_with_json
    @application_instances = [@application_instance]
    set_requests
    render json: json_for(@application_instance)
  end

  def json_for(application_instance)
    authentications = get_authentications(application_instance)
    json = application_instance.as_json(include: :site)
    json["lti_config_xml"] = application_instance.lti_config_xml
    json["canvas_token_preview"] = application_instance.canvas_token_preview
    json.delete("encrypted_canvas_token")
    json.delete("encrypted_canvas_token_salt")
    json.delete("encrypted_canvas_token_iv")
    json["authentications"] = authentications
    json["request_stats"] = request_stats(application_instance.tenant)
    json
  end

  def set_requests
    tenants = @application_instances.pluck(:tenant)
    @day_1_requests_grouped, @day_7_requests_grouped, @day_30_requests_grouped =
      RequestStatistic.total_requests_grouped(tenants)
{'fraction_non_alphanumeric': 0.07582298974635726, 'fraction_numerical': 0.0021586616297895305, 'mean_word_length': 4.336933045356371, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2556317', 'n_tokens_mistral': 2157, 'n_tokens_neox': 2110, 'n_words': 393}