require_relative 'boot'

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
# require "action_mailbox/engine"
# require "action_text/engine"
require "action_view/railtie"
# require "action_cable/engine"
require "rails/test_unit/railtie"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module VideoGameList
  class Application < Rails::Application
    # Initialize configuration defaults for Rails 7.2.
    config.load_defaults 7.2

    # Rails 7.0 changes the digest class for the key generators to `OpenSSL::Digest::SHA256`.
    # Changing this default means invalidate all encrypted messages generated by
    # your application and, all the encrypted cookies. Only change this after you
    # rotated all the messages using the key rotator.
    #
    # See upgrading guide for more information on how to build a rotator.
    # https://guides.rubyonrails.org/v7.0/upgrading_ruby_on_rails.html
    # TODO: Eventually upgrade to OpenSSL::Digest::SHA256. Will need to rotate encrypted data.
    config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1

    # TODO: Upgrade this to SHA256 in the future as well, at the same time as the above.
    config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1

    # TODO: We can remove this after fully upgrading from SHA1 to SHA256 and rotating all encrypted values.
    config.active_record.encryption.support_sha1_for_non_deterministic_encryption = true

    # Disable yjit because our production server is memory constrained.
    config.yjit = false

    # Use structure.sql because we have SQL views, and the schema.rb doesn't support those.
    config.active_record.schema_format = :sql

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.

    config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden

    # Use mini magick explicitly since we haven't upgraded to vips.
    config.active_storage.variant_processor = :mini_magick

    # Allow cross-origin requests to GraphQL, ActiveStorage blobs, and OAuth
    # auth routes.
    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        # Add CORS exception for GraphQL requests.
        resource '/graphql', headers: :any, methods: [:post, :options]
        # Add CORS exception for ActiveStorage blobs.
        resource '/rails/active_storage/*', headers: :any, methods: :get
        # Add CORS exception for OAuth authentication.
        resource '/settings/oauth/token', headers: :any, methods: :post
      end
    end

    # Customize what the rails generate command creates.
    config.generators do |generate|
      # Disable helper generation
      generate.helper false
      # Disable CSS and JavaScript generation
      generate.assets false
      # Disable controller spec generation
      generate.controller_specs false
    end

    # Get the current commit SHA for the Rails app. This will surely have some
    # sort of negative side-effect I haven't figured out yet. This is used for
    # caching to make sure the cache is busted when a new version of the
    # application is deployed.
    # https://brandonhilkert.com/blog/understanding-the-rails-cache-id-environment-variable/
    ENV['GIT_COMMIT_SHA'] = `git rev-parse HEAD`.strip

    config.to_prepare do
      # Only Applications list
      Doorkeeper::ApplicationsController.layout "application"

      # Only Authorization endpoint
      Doorkeeper::AuthorizationsController.layout "application"

      # Only Authorized Applications
      Doorkeeper::AuthorizedApplicationsController.layout "application"
    end

    # Add spec to the directories that 'rails notes' checks.
    config.annotations.register_directories("spec")
    # Add .vue files to the file extensions picked up by 'rails notes'.
    config.annotations.register_extensions("vue") { |annotation| %r{//\s*(#{annotation}):?\s*(.*)$} }
  end
end
