# typed: false
# frozen_string_literal: true

require "English"
require "propshaft"
require "jbuilder"
require "solid_queue"
require "mission_control/jobs"

module Hephaestus
  class Engine < ::Rails::Engine
    isolate_namespace Hephaestus
    config.generators.api_only = true

    GIT_SHA = case Rails.env
    when "production", "staging"
      ENV["GIT_SHA"] || ""
    when "development"
      %x(git rev-parse HEAD)
    when "test"
      "deadbeef"
    end.chomp

    require "hephaestus/http"

    initializer "hephaestus.add_middleware" do |app|
      Hephaestus::Engine.root.glob("lib/hephaestus/middleware/*.{rb}").each { |file| require_relative file }

      app.config.middleware.insert(0, Hephaestus::Middleware::TracingAttributes)
      app.config.middleware.insert(0, Hephaestus::Middleware::MalformedRequest)

      app.config.middleware.use(Hephaestus::Middleware::OpenapiValidation)
    end

    initializer :append_migrations do |app|
      unless app.root.to_s.match?(root.to_s)
        config.paths["db/migrate"].expanded.each do |expanded_path|
          app.config.paths["db/migrate"] << expanded_path
        end
      end
    end

    class << self
      def insert_routes
        Rails.application.routes.draw do
          # Staff pages
          get("staff", to: "staff#index")

          constraints(->(request) { StaffController.staff_request?(request) }) do
            mount(MissionControl::Jobs::Engine, at: "staff/jobs", as: :staff_jobs)
          end

          #############################################
          # error pages -- these MUST be at the end! ##
          #############################################

          get("/500", to: "application#render500") if Rails.env.production? || Rails.env.staging?

          match("/", to: "application#not_found", via: :all)
          match("/*unmatched_route", to: "application#not_found", via: :all)
        end
      end

      def load_environment
        unless Rails.env.local?
          ENV["DATABASE_URL"] = op_read("op://Infra/Plug #{Rails.env.capitalize} Secrets/Common/DATABASE_URL")
        end
      end
    end

    def op_read(label)
      %x(#{include_sudo?}op read "#{label}").chomp.tap do
        raise "Failed to fetch `#{label}` from 1Password" unless $CHILD_STATUS.success?
      end
    end

    def check_dependencies!
      raise "1Password CLI is not installed" unless cli_installed?
    end

    def cli_installed?
      %x(#{include_sudo?}op --version 2> /dev/null)
      $CHILD_STATUS.success?
    end

    def include_sudo?
      ENV.fetch("DOCKER", false) == "1" ? "sudo -E " : ""
    end

    # we need to check if the 1Password CLI is installed and load it ASAP,
    # because it contains all the secrets
    check_dependencies! unless Rails.env.local?
  end
end