module Dependabot

def self.fetcher_error_details(error)

def self.fetcher_error_details(error)
  case error
  when Dependabot::ToolVersionNotSupported
    {
      "error-type": "tool_version_not_supported",
      "error-detail": {
        "tool-name": error.tool_name,
        "detected-version": error.detected_version,
        "supported-versions": error.supported_versions
      }
    }
  when Dependabot::ToolFeatureNotSupported
    {
      "error-type": "tool_feature_not_supported",
      "error-detail": {
        "tool-name": error.tool_name,
        "tool-type": error.tool_type,
        feature: error.feature
      }
    }
  when Dependabot::BranchNotFound
    {
      "error-type": "branch_not_found",
      "error-detail": { "branch-name": error.branch_name }
    }
  when Dependabot::DirectoryNotFound
    {
      "error-type": "directory_not_found",
      "error-detail": { "directory-name": error.directory_name }
    }
  when Dependabot::RepoNotFound
    # This happens if the repo gets removed after a job gets kicked off.
    # This also happens when a configured personal access token is not authz'd to fetch files from the job repo.
    {
      "error-type": "job_repo_not_found",
      "error-detail": { message: error.message }
    }
  when Dependabot::DependencyFileNotParseable
    {
      "error-type": "dependency_file_not_parseable",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::DependencyFileNotFound
    {
      "error-type": "dependency_file_not_found",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::OutOfDisk
    {
      "error-type": "out_of_disk",
      "error-detail": {}
    }
  when Dependabot::PathDependenciesNotReachable
    {
      "error-type": "path_dependencies_not_reachable",
      "error-detail": { dependencies: error.dependencies }
    }
  when Dependabot::PrivateSourceAuthenticationFailure
    {
      "error-type": "private_source_authentication_failure",
      "error-detail": { source: error.source }
    }
  when Dependabot::PrivateSourceBadResponse
    {
      "error-type": "private_source_bad_response",
      "error-detail": { source: error.source }
    }
  when Dependabot::DependencyNotFound
    {
      "error-type": "dependency_not_found",
      "error-detail": { source: error.source }
    }
  when Octokit::Unauthorized
    { "error-type": "octokit_unauthorized" }
  when Octokit::ServerError
    # If we get a 500 from GitHub there's very little we can do about it,
    # and responsibility for fixing it is on them, not us. As a result we
    # quietly log these as errors
    { "error-type": "server_error" }
  when BadRequirementError
    {
      "error-type": "illformed_requirement",
      "error-detail": { message: error.message }
    }
  when *Octokit::RATE_LIMITED_ERRORS
    # If we get a rate-limited error we let dependabot-api handle the
    # retry by re-enqueing the update job after the reset
    {
      "error-type": "octokit_rate_limited",
      "error-detail": {
        "rate-limit-reset": T.cast(error, Octokit::Error).response_headers["X-RateLimit-Reset"]
      }
    }
  end
end

def self.logger

def self.logger
  @logger ||= T.let(::Logger.new(nil), T.nilable(::Logger))
end

def self.logger=(logger)

def self.logger=(logger)
  @logger = logger
end

def self.parser_error_details(error)

def self.parser_error_details(error)
  case error
  when Dependabot::ToolFeatureNotSupported
    {
      "error-type": "tool_feature_not_supported",
      "error-detail": {
        "tool-name": error.tool_name,
        "tool-type": error.tool_type,
        feature: error.feature
      }
    }
  when Dependabot::DependencyFileNotEvaluatable
    {
      "error-type": "dependency_file_not_evaluatable",
      "error-detail": { message: error.message }
    }
  when Dependabot::DependencyFileNotResolvable
    {
      "error-type": "dependency_file_not_resolvable",
      "error-detail": { message: error.message }
    }
  when Dependabot::BranchNotFound
    {
      "error-type": "branch_not_found",
      "error-detail": { "branch-name": error.branch_name }
    }
  when Dependabot::DependencyFileNotParseable
    {
      "error-type": "dependency_file_not_parseable",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::DependencyFileNotFound
    {
      "error-type": "dependency_file_not_found",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::PathDependenciesNotReachable
    {
      "error-type": "path_dependencies_not_reachable",
      "error-detail": { dependencies: error.dependencies }
    }
  when Dependabot::PrivateSourceAuthenticationFailure
    {
      "error-type": "private_source_authentication_failure",
      "error-detail": { source: error.source }
    }
  when Dependabot::PrivateSourceBadResponse
    {
      "error-type": "private_source_bad_response",
      "error-detail": { source: error.source }
    }
  when Dependabot::GitDependenciesNotReachable
    {
      "error-type": "git_dependencies_not_reachable",
      "error-detail": { "dependency-urls": error.dependency_urls }
    }
  when Dependabot::NotImplemented
    {
      "error-type": "not_implemented",
      "error-detail": {
        message: error.message
      }
    }
  when Octokit::ServerError
    # If we get a 500 from GitHub there's very little we can do about it,
    # and responsibility for fixing it is on them, not us. As a result we
    # quietly log these as errors
    { "error-type": "server_error" }
  end
end

def self.updater_error_details(error)

def self.updater_error_details(error)
  case error
  when Dependabot::ToolFeatureNotSupported
    {
      "error-type": "tool_feature_not_supported",
      "error-detail": {
        "tool-name": error.tool_name,
        "tool-type": error.tool_type,
        feature: error.feature
      }
    }
  when Dependabot::DependencyFileNotResolvable
    {
      "error-type": "dependency_file_not_resolvable",
      "error-detail": { message: error.message }
    }
  when Dependabot::DependencyFileNotEvaluatable
    {
      "error-type": "dependency_file_not_evaluatable",
      "error-detail": { message: error.message }
    }
  when Dependabot::DependencyFileNotParseable
    {
      "error-type": "dependency_file_not_parseable",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::DependencyFileNotSupported
    {
      "error-type": "dependency_file_not_supported",
      "error-detail": { message: error.message }
    }
  when Dependabot::GitDependenciesNotReachable
    {
      "error-type": "git_dependencies_not_reachable",
      "error-detail": { "dependency-urls": error.dependency_urls }
    }
  when Dependabot::DependencyFileNotFound
    {
      "error-type": "dependency_file_not_found",
      "error-detail": {
        message: error.message,
        "file-path": error.file_path
      }
    }
  when Dependabot::DependencyFileContentNotChanged
    {
      "error-type": "dependency_file_content_not_changed",
      "error-detail": { message: error.message }
    }
  when Dependabot::ToolVersionNotSupported
    {
      "error-type": "tool_version_not_supported",
      "error-detail": {
        "tool-name": error.tool_name,
        "detected-version": error.detected_version,
        "supported-versions": error.supported_versions
      }
    }
  when Dependabot::MisconfiguredTooling
    {
      "error-type": "misconfigured_tooling",
      "error-detail": { "tool-name": error.tool_name, message: error.tool_message }
    }
  when Dependabot::GitDependencyReferenceNotFound
    {
      "error-type": "git_dependency_reference_not_found",
      "error-detail": { dependency: error.dependency }
    }
  when Dependabot::PrivateSourceAuthenticationFailure
    {
      "error-type": "private_source_authentication_failure",
      "error-detail": { source: error.source }
    }
  when Dependabot::PrivateSourceBadResponse
    {
      "error-type": "private_source_bad_response",
      "error-detail": { source: error.source }
    }
  when Dependabot::DependencyNotFound
    {
      "error-type": "dependency_not_found",
      "error-detail": { source: error.source }
    }
  when Dependabot::PrivateSourceTimedOut
    {
      "error-type": "private_source_timed_out",
      "error-detail": { source: error.source }
    }
  when Dependabot::PrivateSourceCertificateFailure
    {
      "error-type": "private_source_certificate_failure",
      "error-detail": { source: error.source }
    }
  when Dependabot::MissingEnvironmentVariable
    {
      "error-type": "missing_environment_variable",
      "error-detail": {
        "environment-variable": error.environment_variable,
        "error-message": error.message
      }
    }
  when Dependabot::OutOfDisk
    {
      "error-type": "out_of_disk",
      "error-detail": {}
    }
  when Dependabot::GoModulePathMismatch
    {
      "error-type": "go_module_path_mismatch",
      "error-detail": {
        "declared-path": error.declared_path,
        "discovered-path": error.discovered_path,
        "go-mod": error.go_mod
      }
    }
  when Dependabot::UpdateNotPossible
    {
      "error-type": "update_not_possible",
      "error-detail": {
        dependencies: error.dependencies
      }
    }
  when BadRequirementError
    {
      "error-type": "illformed_requirement",
      "error-detail": { message: error.message }
    }
  when RegistryError
    {
      "error-type": "registry_error",
      "error-detail": { status: error.status,
                        msg: error.message }
    }
  when
    IncompatibleCPU,
    NetworkUnsafeHTTP
    error.detail
  when Dependabot::NotImplemented
    {
      "error-type": "not_implemented",
      "error-detail": {
        message: error.message
      }
    }
  when Dependabot::InvalidGitAuthToken
    {
      "error-type": "git_token_auth_error",
      "error-detail": { message: error.message }
    }
  when *Octokit::RATE_LIMITED_ERRORS
    # If we get a rate-limited error we let dependabot-api handle the
    # retry by re-enqueing the update job after the reset
    {
      "error-type": "octokit_rate_limited",
      "error-detail": {
        "rate-limit-reset": T.cast(error, Octokit::Error).response_headers["X-RateLimit-Reset"]
      }
    }
  end
end