# frozen_string_literal: true

Gitlab::GrapeOpenapi.configure do |config|
  config.info = Gitlab::GrapeOpenapi::Models::Info.new(
    title: 'GitLab REST API',
    description: 'GitLab REST API used to interact with a GitLab installation.',
    version: 'v4',
    terms_of_service: 'https://handbook.gitlab.com/handbook/legal/api-terms/',
    license: {
      name: 'CC BY-SA 4.0',
      url: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/LICENSE',
      'x-gitlab-description':
        'The license applies to the OpenAPI specification document itself. ' \
        'For terms governing use of the GitLab API, see the termsOfService field.'
    }
  )

  config.api_prefix = "api"

  config.api_version = "v4"

  config.servers = [
    Gitlab::GrapeOpenapi::Models::Server.new(
      url: 'https://{hostname}',
      description: "GitLab REST API",
      variables: {
        hostname: Gitlab::GrapeOpenapi::Models::ServerVariable.new(
          default: 'gitlab.com',
          description: 'Your GitLab instance hostname'
        )
      }
    )
  ]

  config.security_schemes = [
    Gitlab::GrapeOpenapi::Models::SecurityScheme.new(
      name: "bearerAuth",
      type: "http",
      scheme: "bearer"
    ),
    Gitlab::GrapeOpenapi::Models::SecurityScheme.new(
      name: "OAuth2",
      type: "oauth2",
      flows: {
        authorizationCode: {
          authorizationUrl: Gitlab::Utils.append_path('https://gitlab.com/api', "/oauth/authorize"),
          tokenUrl: Gitlab::Utils.append_path('https://gitlab.com/api', "/oauth/token"),
          refreshUrl: Gitlab::Utils.append_path('https://gitlab.com/api', "/oauth/refresh"),
          scopes: -> {
            Gitlab::Auth::API_SCOPES.reject { |k, _| k == :granular }
                                  .index_with { |s| I18n.t(s, scope: [:doorkeeper, :scope_desc]) }
          }
        }
      }
    )
  ]

  # key: `route_setting` value
  # value: rendered annotation key
  # e.g. route_setting :lifecycle, "experimental" => YAML: `x-gitlab-lifecycle: experimental`
  config.annotations = {
    lifecycle: 'x-gitlab-lifecycle'
  }

  config.tag_overrides = {
    'Ai catalog' => 'AI Catalog',
    'Api' => 'API',
    'bitbucket' => 'Bitbucket',
    'Ci' => 'CI',
    'Dora' => 'DORA',
    'Duo workflows' => 'Duo Workflows',
    'geo' => 'Geo',
    'Github' => 'GitHub',
    'Gitlab duo' => 'GitLab Duo',
    'Gitlab pages' => 'GitLab Pages',
    'Gitlab' => 'GitLab',
    'Gpg' => 'GPG',
    'Glql' => 'GLQL',
    'google cloud' => 'Google Cloud',
    'Jira connect' => 'Jira Connect',
    'Ldap' => 'LDAP',
    'markdown' => 'Markdown',
    'Ml model registry' => 'ML Model Registry',
    'Mlops' => 'MLOps',
    'Mcp' => 'MCP',
    'Npm' => 'NPM',
    'Oauth' => 'OAuth',
    'Pypi' => 'PyPi',
    'Rpm' => 'RPM',
    'Rubygem' => 'RubyGem',
    'Saml' => 'SAML',
    'Scim' => 'SCIM',
    'sidekiq' => 'Sidekiq',
    'Ssh' => 'SSH',
    'Terraform' => 'Terraform',
    'Todos' => 'To-Dos',
    'unleash' => 'Unleash',
    'Vscode' => 'VSCode',
    # Package Registry: render per-format tags as "Packages: <Format>" so they
    # cluster together in the API reference sidebar.
    'Packages cargo' => 'Packages: Cargo',
    'Packages composer' => 'Packages: Composer',
    'Packages conan' => 'Packages: Conan',
    'Packages debian' => 'Packages: Debian',
    'Packages helm' => 'Packages: Helm',
    'Packages npm' => 'Packages: NPM',
    'Packages nuget' => 'Packages: NuGet',
    'Packages pypi' => 'Packages: PyPi',
    'Packages rpm' => 'Packages: RPM',
    'Packages rubygem' => 'Packages: RubyGem'
  }.freeze

  # CONFIGURE COERCER MAPPINGS
  # Maps coerce_with classes to OpenAPI schema properties.
  # When a parameter uses coerce_with and the coercer matches a pattern below,
  # the OpenAPI schema will be generated according to the mapping.
  # For query parameters, style and explode control URL serialization format.
  config.coercer_mappings = {
    # Comma-separated string -> Array of strings (e.g., "bug,feature" -> ["bug", "feature"])
    "CommaSeparatedToArray" => {
      type: "array",
      items_type: "string",
      style: "form",
      explode: false
    },
    # Comma-separated string -> Array of integers (e.g., "1,2,3" -> [1, 2, 3])
    "CommaSeparatedToIntegerArray" => {
      type: "array",
      items_type: "integer",
      style: "form",
      explode: false
    },
    # Hash with string keys -> Hash with integer values
    "HashOfIntegerValues" => {
      type: "object",
      additional_properties: { type: "integer" }
    },
    # Base64-encoded string -> Decoded bytes
    "urlsafe_decode64" => {
      type: "string",
      format: "byte"
    }
  }.freeze

  # CONFIGURE EXCLUDED APIs
  # API endpoints can be excluded from OpenApi spec generation and the resulting
  # documentation by adding their API classes to the excluded_api_classes array.
  # Grape API classes are not loaded when this config is intitialized.
  # Only use string names. Using class constants will cause loading errors.
  # eg.  config.excluded_api_classes = [ 'API::InternalApiClass', 'API::AdminApiClass' ]
  config.excluded_api_classes = [
    'GitlabSubscriptions::API::Internal::Users',
    'GitlabSubscriptions::API::Internal::UpcomingReconciliations',
    'GitlabSubscriptions::API::Internal::Subscriptions',
    'GitlabSubscriptions::API::Internal::Namespaces::Provision',
    'GitlabSubscriptions::API::Internal::Namespaces',
    'GitlabSubscriptions::API::Internal::Members',
    'GitlabSubscriptions::API::Internal::ComputeMinutes',
    'GitlabSubscriptions::API::Internal::AddOnPurchases',
    'GitlabSubscriptions::API::Internal::API',
    'API::Internal::SecretsManager',
    # Beta endpoint, excluded from OpenAPI until it reaches general availability.
    'API::SecretsManagement::AccessTokens',
    'API::Internal::Observability',
    'API::Internal::Search::Zoekt',
    'API::Internal::Ci::JobRouter',
    'API::Internal::AppSec::Dast::SiteValidations',
    'API::RemoteDevelopment::Internal::Agents::Agentw::ServerConfig',
    'API::RemoteDevelopment::Internal::Agents::Agentw::AuthorizeUserAccess',
    'API::RemoteDevelopment::Internal::Agents::Agentw::AgentInfo',
    'API::Internal::Shellhorse',
    'API::Internal::Workhorse',
    'API::Internal::MailRoom',
    'API::Internal::ErrorTracking',
    'API::Internal::Kubernetes',
    'API::Internal::Pages',
    'API::Internal::Lfs',
    'API::Internal::Base',
    'API::Internal::Coverage',
    'API::Scim::InstanceScim',
    'API::Scim::GroupScim'
  ]
end
