class Provider::Admin::AuthenticationProvidersController < FrontendController
  activate_menu :settings, :portal, :oauth2
  sublayout 'sites/developer_portals'

  before_action :find_authentication_provider, only: %i[show edit update destroy]
  before_action :build_authentication_provider, only: %i[create]

  def index
    @authentication_providers = current_account.authentication_provider_kinds
  end

  def new
    existing = authentication_providers.find_by(kind: params[:kind].presence)

    if existing
      return redirect_to provider_admin_authentication_provider_path(existing)
    end

    build_authentication_provider(params)

    if @authentication_provider.save
      redirect_to provider_admin_authentication_provider_path(@authentication_provider)
    else
      @authentication_provider.errors.clear
    end
  end

  def show
    if @authentication_provider.in_iam_tools_scope? # TODO: remove this condition and authorize always
      authorize! :manage, @authentication_provider.authorization_scope
    end
    @oauth_presenter = OauthFlowPresenter.new(@authentication_provider, request)
  end

  def create
    if @authentication_provider.save
      redirect_to edit_provider_admin_authentication_provider_path(@authentication_provider), notice: 'Authentication provider created'
    else
      render 'new'
    end
  end

  def edit
  end

  def update
    persisted = @authentication_provider.update_attributes(authentication_provider_params)

    @oauth_presenter = OauthFlowPresenter.new(@authentication_provider, request)

    respond_to do |format|
      if persisted
        format.html do
          redirect_to provider_admin_authentication_provider_path(@authentication_provider),
                      notice: 'Authentication provider updated'
        end
      else
        format.html { render :edit }
      end

      format.js
    end
  end

  def destroy
    @authentication_provider.destroy
    redirect_to provider_admin_authentication_providers_path, notice: 'Authentication provider deleted'
  end

  private

  def authorize_authentication_provider!(authentication_provider)
    if (scope = authentication_provider.authorization_scope(action_name))
      authorize! :manage, scope
    end

    @authentication_provider = authentication_provider
  end

  def build_authentication_provider(params = authentication_provider_params)
    authentication_provider = authentication_providers.build_kind(params.require(:kind))
    authentication_provider.attributes = params if params.permitted?

    authorize_authentication_provider! authentication_provider
  end

  def find_authentication_provider
    authorize_authentication_provider! authentication_providers.find(params[:id])
  end

  def authentication_providers
    current_account.authentication_providers
  end

  # FIXME: this is really not secure, anyone can just update any parameter
  # we should fix this by allowing just subsets depending on the state
  def authentication_provider_params
    params.require(:authentication_provider).permit(
      :name, :system_name, :client_id, :client_secret,
      :token_url, :user_info_url, :authorize_url, :site, :realm,
      :identifier_key, :username_key, :trust_email, :kind,
      :published, :branding_state_event, :skip_ssl_certificate_verification
    )
  end
end
