Skip to main content

lib/api/repos/repos.ex

# Generated by `mix github.gen` from docs/github-api/api.github.com.json.
# Do not edit by hand; re-run the task instead.

defmodule Noizu.Github.Api.Repos do
  @moduledoc """
  GitHub `repos` API.
  """
  import Noizu.Github

  @doc """
  Accept a repository invitation

  @see https://docs.github.com/rest/collaborators/invitations#accept-a-repository-invitation
  """
  def accept_invitation_for_authenticated_user(invitation_id, body, options \\ nil) do
    url = github_base() <> "/user/repository_invitations/#{invitation_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Add app access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#add-app-access-restrictions
  """
  def add_app_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/apps"

    body = body
    api_call(:post, url, body, Noizu.Github.Collection.Integration, options)
  end

  @doc """
  Add a repository collaborator

  @see https://docs.github.com/rest/collaborators/collaborators#add-a-repository-collaborator
  """
  def add_collaborator(username, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/collaborators/#{username}"
    body = body
    api_call(:put, url, body, Noizu.Github.RepositoryInvitation, options)
  end

  @doc """
  Add status check contexts

  @see https://docs.github.com/rest/branches/branch-protection#add-status-check-contexts
  """
  def add_status_check_contexts(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks/contexts"

    body = body
    api_call(:post, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Add team access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#add-team-access-restrictions
  """
  def add_team_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/teams"

    body = body
    api_call(:post, url, body, Noizu.Github.Collection.Team, options)
  end

  @doc """
  Add user access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#add-user-access-restrictions
  """
  def add_user_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/users"

    body = body
    api_call(:post, url, body, Noizu.Github.Collection.SimpleUser, options)
  end

  @doc """
  Cancel a GitHub Pages deployment

  @see https://docs.github.com/rest/pages/pages#cancel-a-github-pages-deployment
  """
  def cancel_pages_deployment(pages_deployment_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/pages/deployments/#{pages_deployment_id}/cancel"

    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Check if Dependabot security updates are enabled for a repository

  @see https://docs.github.com/rest/repos/repos#check-if-dependabot-security-updates-are-enabled-for-a-repository
  """
  def check_automated_security_fixes(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/automated-security-fixes"
    body = %{}
    api_call(:get, url, body, Noizu.Github.CheckAutomatedSecurityFixes, options)
  end

  @doc """
  Check if a user is a repository collaborator

  @see https://docs.github.com/rest/collaborators/collaborators#check-if-a-user-is-a-repository-collaborator
  """
  def check_collaborator(username, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/collaborators/#{username}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Check if immutable releases are enabled for a repository

  @see https://docs.github.com/rest/repos/repos#check-if-immutable-releases-are-enabled-for-a-repository
  """
  def check_immutable_releases(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/immutable-releases"
    body = %{}
    api_call(:get, url, body, Noizu.Github.CheckImmutableReleases, options)
  end

  @doc """
  Check if private vulnerability reporting is enabled for a repository

  @see https://docs.github.com/rest/repos/repos#check-if-private-vulnerability-reporting-is-enabled-for-a-repository
  """
  def check_private_vulnerability_reporting(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/private-vulnerability-reporting"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Check if vulnerability alerts are enabled for a repository

  @see https://docs.github.com/rest/repos/repos#check-if-vulnerability-alerts-are-enabled-for-a-repository
  """
  def check_vulnerability_alerts(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/vulnerability-alerts"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  List CODEOWNERS errors

  @see https://docs.github.com/rest/repos/repos#list-codeowners-errors
  """
  def codeowners_errors(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:ref, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/codeowners/errors" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.CodeownersErrors, options)
  end

  @doc """
  Compare two commits

  @see https://docs.github.com/rest/commits/commits#compare-two-commits
  """
  def compare_commits(basehead, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:page, options, nil),
            get_field(:per_page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/compare/#{basehead}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.CommitComparison, options)
  end

  @doc """
  Create an attestation

  @see https://docs.github.com/rest/repos/attestations#create-an-attestation
  """
  def create_attestation(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/attestations"
    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Create an autolink reference for a repository

  @see https://docs.github.com/rest/repos/autolinks#create-an-autolink-reference-for-a-repository
  """
  def create_autolink(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/autolinks"
    body = body
    api_call(:post, url, body, Noizu.Github.Autolink, options)
  end

  @doc """
  Create a commit comment

  @see https://docs.github.com/rest/commits/comments#create-a-commit-comment
  """
  def create_commit_comment(commit_sha, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/commits/#{commit_sha}/comments"
    body = body
    api_call(:post, url, body, Noizu.Github.CommitComment, options)
  end

  @doc """
  Create commit signature protection

  @see https://docs.github.com/rest/branches/branch-protection#create-commit-signature-protection
  """
  def create_commit_signature_protection(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_signatures"

    body = body
    api_call(:post, url, body, Noizu.Github.ProtectedBranchAdminEnforced, options)
  end

  @doc """
  Create a commit status

  @see https://docs.github.com/rest/commits/statuses#create-a-commit-status
  """
  def create_commit_status(sha, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/statuses/#{sha}"
    body = body
    api_call(:post, url, body, Noizu.Github.Status, options)
  end

  @doc """
  Create a deploy key

  @see https://docs.github.com/rest/deploy-keys/deploy-keys#create-a-deploy-key
  """
  def create_deploy_key(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/keys"
    body = body
    api_call(:post, url, body, Noizu.Github.DeployKey, options)
  end

  @doc """
  Create a deployment

  @see https://docs.github.com/rest/deployments/deployments#create-a-deployment
  """
  def create_deployment(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/deployments"
    body = body
    api_call(:post, url, body, Noizu.Github.Deployment, options)
  end

  @doc """
  Create a deployment branch policy

  @see https://docs.github.com/rest/deployments/branch-policies#create-a-deployment-branch-policy
  """
  def create_deployment_branch_policy(environment_name, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment-branch-policies"

    body = body
    api_call(:post, url, body, Noizu.Github.DeploymentBranchPolicy, options)
  end

  @doc """
  Create a custom deployment protection rule on an environment

  @see https://docs.github.com/rest/deployments/protection-rules#create-a-custom-deployment-protection-rule-on-an-environment
  """
  def create_deployment_protection_rule(environment_name, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment_protection_rules"

    body = body
    api_call(:post, url, body, Noizu.Github.DeploymentProtectionRule, options)
  end

  @doc """
  Create a deployment status

  @see https://docs.github.com/rest/deployments/statuses#create-a-deployment-status
  """
  def create_deployment_status(deployment_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/deployments/#{deployment_id}/statuses"
    body = body
    api_call(:post, url, body, Noizu.Github.DeploymentStatus, options)
  end

  @doc """
  Create a repository dispatch event

  @see https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event
  """
  def create_dispatch_event(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/dispatches"
    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Create a repository for the authenticated user

  @see https://docs.github.com/rest/repos/repos#create-a-repository-for-the-authenticated-user
  """
  def create_for_authenticated_user(body, options \\ nil) do
    url = github_base() <> "/user/repos"
    body = body
    api_call(:post, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Create a fork

  @see https://docs.github.com/rest/repos/forks#create-a-fork
  """
  def create_fork(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/forks"
    body = body
    api_call(:post, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Create an organization repository

  @see https://docs.github.com/rest/repos/repos#create-an-organization-repository
  """
  def create_in_org(org, body, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/repos"
    body = body
    api_call(:post, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Create or update an environment

  @see https://docs.github.com/rest/deployments/environments#create-or-update-an-environment
  """
  def create_or_update_environment(environment_name, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/environments/#{environment_name}"
    body = body
    api_call(:put, url, body, Noizu.Github.Environment, options)
  end

  @doc """
  Create or update file contents

  @see https://docs.github.com/rest/repos/contents#create-or-update-file-contents
  """
  def create_or_update_file_contents(path, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/contents/#{path}"
    body = body
    api_call(:put, url, body, Noizu.Github.FileCommit, options)
  end

  @doc """
  Create an organization repository ruleset

  @see https://docs.github.com/rest/orgs/rules#create-an-organization-repository-ruleset
  """
  def create_org_ruleset(org, body, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/rulesets"
    body = body
    api_call(:post, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Create a GitHub Pages deployment

  @see https://docs.github.com/rest/pages/pages#create-a-github-pages-deployment
  """
  def create_pages_deployment(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/deployments"
    body = body
    api_call(:post, url, body, Noizu.Github.PageDeployment, options)
  end

  @doc """
  Create a GitHub Pages site

  @see https://docs.github.com/rest/pages/pages#create-a-apiname-pages-site
  """
  def create_pages_site(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages"
    body = body
    api_call(:post, url, body, Noizu.Github.Page, options)
  end

  @doc """
  Create a release

  @see https://docs.github.com/rest/releases/releases#create-a-release
  """
  def create_release(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases"
    body = body
    api_call(:post, url, body, Noizu.Github.Release, options)
  end

  @doc """
  Create a repository ruleset

  @see https://docs.github.com/rest/repos/rules#create-a-repository-ruleset
  """
  def create_repo_ruleset(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/rulesets"
    body = body
    api_call(:post, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Create a repository using a template

  @see https://docs.github.com/rest/repos/repos#create-a-repository-using-a-template
  """
  def create_using_template(template_owner, template_repo, body, options \\ nil) do
    url = github_base() <> "/repos/#{template_owner}/#{template_repo}/generate"
    body = body
    api_call(:post, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Create a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#create-a-repository-webhook
  """
  def create_webhook(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks"
    body = body
    api_call(:post, url, body, Noizu.Github.Hook, options)
  end

  @doc """
  Create or update custom property values for a repository

  @see https://docs.github.com/rest/repos/custom-properties#create-or-update-custom-property-values-for-a-repository
  """
  def custom_properties_for_repos_create_or_update_repository_values(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/properties/values"
    body = body
    api_call(:patch, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get all custom property values for a repository

  @see https://docs.github.com/rest/repos/custom-properties#get-all-custom-property-values-for-a-repository
  """
  def custom_properties_for_repos_get_repository_values(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/properties/values"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.CustomPropertyValue, options)
  end

  @doc """
  Decline a repository invitation

  @see https://docs.github.com/rest/collaborators/invitations#decline-a-repository-invitation
  """
  def decline_invitation_for_authenticated_user(invitation_id, options \\ nil) do
    url = github_base() <> "/user/repository_invitations/#{invitation_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a repository

  @see https://docs.github.com/rest/repos/repos#delete-a-repository
  """
  def delete(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#delete-access-restrictions
  """
  def delete_access_restrictions(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete admin branch protection

  @see https://docs.github.com/rest/branches/branch-protection#delete-admin-branch-protection
  """
  def delete_admin_branch_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/enforce_admins"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete an environment

  @see https://docs.github.com/rest/deployments/environments#delete-an-environment
  """
  def delete_an_environment(environment_name, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/environments/#{environment_name}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete an autolink reference from a repository

  @see https://docs.github.com/rest/repos/autolinks#delete-an-autolink-reference-from-a-repository
  """
  def delete_autolink(autolink_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/autolinks/#{autolink_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete branch protection

  @see https://docs.github.com/rest/branches/branch-protection#delete-branch-protection
  """
  def delete_branch_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a commit comment

  @see https://docs.github.com/rest/commits/comments#delete-a-commit-comment
  """
  def delete_commit_comment(comment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/comments/#{comment_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete commit signature protection

  @see https://docs.github.com/rest/branches/branch-protection#delete-commit-signature-protection
  """
  def delete_commit_signature_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_signatures"

    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a deploy key

  @see https://docs.github.com/rest/deploy-keys/deploy-keys#delete-a-deploy-key
  """
  def delete_deploy_key(key_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/keys/#{key_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a deployment

  @see https://docs.github.com/rest/deployments/deployments#delete-a-deployment
  """
  def delete_deployment(deployment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/deployments/#{deployment_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a deployment branch policy

  @see https://docs.github.com/rest/deployments/branch-policies#delete-a-deployment-branch-policy
  """
  def delete_deployment_branch_policy(environment_name, branch_policy_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment-branch-policies/#{branch_policy_id}"

    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a file

  @see https://docs.github.com/rest/repos/contents#delete-a-file
  """
  def delete_file(path, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/contents/#{path}"
    body = body
    api_call(:delete, url, body, Noizu.Github.FileCommit, options)
  end

  @doc """
  Delete a repository invitation

  @see https://docs.github.com/rest/collaborators/invitations#delete-a-repository-invitation
  """
  def delete_invitation(invitation_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/invitations/#{invitation_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete an organization repository ruleset

  @see https://docs.github.com/rest/orgs/rules#delete-an-organization-repository-ruleset
  """
  def delete_org_ruleset(org, ruleset_id, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/rulesets/#{ruleset_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a GitHub Pages site

  @see https://docs.github.com/rest/pages/pages#delete-a-apiname-pages-site
  """
  def delete_pages_site(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete pull request review protection

  @see https://docs.github.com/rest/branches/branch-protection#delete-pull-request-review-protection
  """
  def delete_pull_request_review_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_pull_request_reviews"

    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a release

  @see https://docs.github.com/rest/releases/releases#delete-a-release
  """
  def delete_release(release_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/#{release_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a release asset

  @see https://docs.github.com/rest/releases/assets#delete-a-release-asset
  """
  def delete_release_asset(asset_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/assets/#{asset_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a repository ruleset

  @see https://docs.github.com/rest/repos/rules#delete-a-repository-ruleset
  """
  def delete_repo_ruleset(ruleset_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/rulesets/#{ruleset_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Delete a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#delete-a-repository-webhook
  """
  def delete_webhook(hook_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Disable Dependabot security updates

  @see https://docs.github.com/rest/repos/repos#disable-dependabot-security-updates
  """
  def disable_automated_security_fixes(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/automated-security-fixes"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Disable a custom protection rule for an environment

  @see https://docs.github.com/rest/deployments/protection-rules#disable-a-custom-protection-rule-for-an-environment
  """
  def disable_deployment_protection_rule(environment_name, protection_rule_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment_protection_rules/#{protection_rule_id}"

    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Disable immutable releases

  @see https://docs.github.com/rest/repos/repos#disable-immutable-releases
  """
  def disable_immutable_releases(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/immutable-releases"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Disable private vulnerability reporting for a repository

  @see https://docs.github.com/rest/repos/repos#disable-private-vulnerability-reporting-for-a-repository
  """
  def disable_private_vulnerability_reporting(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/private-vulnerability-reporting"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Disable vulnerability alerts

  @see https://docs.github.com/rest/repos/repos#disable-vulnerability-alerts
  """
  def disable_vulnerability_alerts(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/vulnerability-alerts"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Download a repository archive (tar)

  @see https://docs.github.com/rest/repos/contents#download-a-repository-archive-tar
  """
  def download_tarball_archive(ref, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/tarball/#{ref}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Download a repository archive (zip)

  @see https://docs.github.com/rest/repos/contents#download-a-repository-archive-zip
  """
  def download_zipball_archive(ref, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/zipball/#{ref}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Enable Dependabot security updates

  @see https://docs.github.com/rest/repos/repos#enable-dependabot-security-updates
  """
  def enable_automated_security_fixes(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/automated-security-fixes"
    body = body
    api_call(:put, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Enable immutable releases

  @see https://docs.github.com/rest/repos/repos#enable-immutable-releases
  """
  def enable_immutable_releases(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/immutable-releases"
    body = body
    api_call(:put, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Enable private vulnerability reporting for a repository

  @see https://docs.github.com/rest/repos/repos#enable-private-vulnerability-reporting-for-a-repository
  """
  def enable_private_vulnerability_reporting(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/private-vulnerability-reporting"
    body = body
    api_call(:put, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Enable vulnerability alerts

  @see https://docs.github.com/rest/repos/repos#enable-vulnerability-alerts
  """
  def enable_vulnerability_alerts(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/vulnerability-alerts"
    body = body
    api_call(:put, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Generate release notes content for a release

  @see https://docs.github.com/rest/releases/releases#generate-release-notes-content-for-a-release
  """
  def generate_release_notes(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/generate-notes"
    body = body
    api_call(:post, url, body, Noizu.Github.ReleaseNotesContent, options)
  end

  @doc """
  Get a repository

  @see https://docs.github.com/rest/repos/repos#get-a-repository
  """
  def get(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Get access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#get-access-restrictions
  """
  def get_access_restrictions(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions"
    body = %{}
    api_call(:get, url, body, Noizu.Github.BranchRestrictionPolicy, options)
  end

  @doc """
  Get admin branch protection

  @see https://docs.github.com/rest/branches/branch-protection#get-admin-branch-protection
  """
  def get_admin_branch_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/enforce_admins"
    body = %{}
    api_call(:get, url, body, Noizu.Github.ProtectedBranchAdminEnforced, options)
  end

  @doc """
  Get all deployment protection rules for an environment

  @see https://docs.github.com/rest/deployments/protection-rules#get-all-deployment-protection-rules-for-an-environment
  """
  def get_all_deployment_protection_rules(environment_name, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment_protection_rules"

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  List environments

  @see https://docs.github.com/rest/deployments/environments#list-environments
  """
  def get_all_environments(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/environments" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get all status check contexts

  @see https://docs.github.com/rest/branches/branch-protection#get-all-status-check-contexts
  """
  def get_all_status_check_contexts(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks/contexts"

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Get all repository topics

  @see https://docs.github.com/rest/repos/repos#get-all-repository-topics
  """
  def get_all_topics(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:page, options, nil),
            get_field(:per_page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/topics" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Topic, options)
  end

  @doc """
  Get apps with access to the protected branch

  @see https://docs.github.com/rest/branches/branch-protection#get-apps-with-access-to-the-protected-branch
  """
  def get_apps_with_access_to_protected_branch(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/apps"

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Integration, options)
  end

  @doc """
  Get an autolink reference of a repository

  @see https://docs.github.com/rest/repos/autolinks#get-an-autolink-reference-of-a-repository
  """
  def get_autolink(autolink_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/autolinks/#{autolink_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Autolink, options)
  end

  @doc """
  Get a branch

  @see https://docs.github.com/rest/branches/branches#get-a-branch
  """
  def get_branch(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.BranchWithProtection, options)
  end

  @doc """
  Get branch protection

  @see https://docs.github.com/rest/branches/branch-protection#get-branch-protection
  """
  def get_branch_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection"
    body = %{}
    api_call(:get, url, body, Noizu.Github.BranchProtection, options)
  end

  @doc """
  Get rules for a branch

  @see https://docs.github.com/rest/repos/rules#get-rules-for-a-branch
  """
  def get_branch_rules(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/rules/branches/#{branch}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Get repository clones

  @see https://docs.github.com/rest/metrics/traffic#get-repository-clones
  """
  def get_clones(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/traffic/clones" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.CloneTraffic, options)
  end

  @doc """
  Get the weekly commit activity

  @see https://docs.github.com/rest/metrics/statistics#get-the-weekly-commit-activity
  """
  def get_code_frequency_stats(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/stats/code_frequency"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Get repository permissions for a user

  @see https://docs.github.com/rest/collaborators/collaborators#get-repository-permissions-for-a-user
  """
  def get_collaborator_permission_level(username, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/collaborators/#{username}/permission"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RepositoryCollaboratorPermission, options)
  end

  @doc """
  Get the combined status for a specific reference

  @see https://docs.github.com/rest/commits/statuses#get-the-combined-status-for-a-specific-reference
  """
  def get_combined_status_for_ref(ref, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits/#{ref}/status" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.CombinedCommitStatus, options)
  end

  @doc """
  Get a commit

  @see https://docs.github.com/rest/commits/commits#get-a-commit
  """
  def get_commit(ref, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:page, options, nil),
            get_field(:per_page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits/#{ref}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Commit, options)
  end

  @doc """
  Get the last year of commit activity

  @see https://docs.github.com/rest/metrics/statistics#get-the-last-year-of-commit-activity
  """
  def get_commit_activity_stats(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/stats/commit_activity"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.CommitActivity, options)
  end

  @doc """
  Get a commit comment

  @see https://docs.github.com/rest/commits/comments#get-a-commit-comment
  """
  def get_commit_comment(comment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/comments/#{comment_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.CommitComment, options)
  end

  @doc """
  Get commit signature protection

  @see https://docs.github.com/rest/branches/branch-protection#get-commit-signature-protection
  """
  def get_commit_signature_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_signatures"

    body = %{}
    api_call(:get, url, body, Noizu.Github.ProtectedBranchAdminEnforced, options)
  end

  @doc """
  Get community profile metrics

  @see https://docs.github.com/rest/metrics/community#get-community-profile-metrics
  """
  def get_community_profile_metrics(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/community/profile"
    body = %{}
    api_call(:get, url, body, Noizu.Github.CommunityProfile, options)
  end

  @doc """
  Get repository content

  @see https://docs.github.com/rest/repos/contents#get-repository-content
  """
  def get_content(path, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:ref, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/contents/#{path}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get all contributor commit activity

  @see https://docs.github.com/rest/metrics/statistics#get-all-contributor-commit-activity
  """
  def get_contributors_stats(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/stats/contributors"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.ContributorActivity, options)
  end

  @doc """
  Get a custom deployment protection rule

  @see https://docs.github.com/rest/deployments/protection-rules#get-a-custom-deployment-protection-rule
  """
  def get_custom_deployment_protection_rule(environment_name, protection_rule_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment_protection_rules/#{protection_rule_id}"

    body = %{}
    api_call(:get, url, body, Noizu.Github.DeploymentProtectionRule, options)
  end

  @doc """
  Get a deploy key

  @see https://docs.github.com/rest/deploy-keys/deploy-keys#get-a-deploy-key
  """
  def get_deploy_key(key_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/keys/#{key_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.DeployKey, options)
  end

  @doc """
  Get a deployment

  @see https://docs.github.com/rest/deployments/deployments#get-a-deployment
  """
  def get_deployment(deployment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/deployments/#{deployment_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Deployment, options)
  end

  @doc """
  Get a deployment branch policy

  @see https://docs.github.com/rest/deployments/branch-policies#get-a-deployment-branch-policy
  """
  def get_deployment_branch_policy(environment_name, branch_policy_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment-branch-policies/#{branch_policy_id}"

    body = %{}
    api_call(:get, url, body, Noizu.Github.DeploymentBranchPolicy, options)
  end

  @doc """
  Get a deployment status

  @see https://docs.github.com/rest/deployments/statuses#get-a-deployment-status
  """
  def get_deployment_status(deployment_id, status_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/deployments/#{deployment_id}/statuses/#{status_id}"

    body = %{}
    api_call(:get, url, body, Noizu.Github.DeploymentStatus, options)
  end

  @doc """
  Get an environment

  @see https://docs.github.com/rest/deployments/environments#get-an-environment
  """
  def get_environment(environment_name, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/environments/#{environment_name}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Environment, options)
  end

  @doc """
  Get the hash algorithm for a repository

  @see https://docs.github.com/rest/repos/repos#get-the-hash-algorithm-for-a-repository
  """
  def get_hash_algorithm(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hash-algorithm"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RepositoryHashAlgorithm, options)
  end

  @doc """
  Get latest Pages build

  @see https://docs.github.com/rest/pages/pages#get-latest-pages-build
  """
  def get_latest_pages_build(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/builds/latest"
    body = %{}
    api_call(:get, url, body, Noizu.Github.PageBuild, options)
  end

  @doc """
  Get the latest release

  @see https://docs.github.com/rest/releases/releases#get-the-latest-release
  """
  def get_latest_release(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/latest"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Release, options)
  end

  @doc """
  Get an organization rule suite

  @see https://docs.github.com/rest/orgs/rule-suites#get-an-organization-rule-suite
  """
  def get_org_rule_suite(org, rule_suite_id, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/rulesets/rule-suites/#{rule_suite_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RuleSuite, options)
  end

  @doc """
  List organization rule suites

  @see https://docs.github.com/rest/orgs/rule-suites#list-organization-rule-suites
  """
  def get_org_rule_suites(org, options \\ nil) do
    url =
      (
        query =
          [
            get_field(:ref, options, nil),
            get_field(:repository_name, options, nil),
            get_field(:time_period, options, nil),
            get_field(:actor_name, options, nil),
            get_field(:rule_suite_result, options, nil),
            get_field(:evaluate_status, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/orgs/#{org}/rulesets/rule-suites" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get an organization repository ruleset

  @see https://docs.github.com/rest/orgs/rules#get-an-organization-repository-ruleset
  """
  def get_org_ruleset(org, ruleset_id, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/rulesets/#{ruleset_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Get all organization repository rulesets

  @see https://docs.github.com/rest/orgs/rules#get-all-organization-repository-rulesets
  """
  def get_org_rulesets(org, options \\ nil) do
    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil),
            get_field(:targets, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/orgs/#{org}/rulesets" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.RepositoryRuleset, options)
  end

  @doc """
  Get a GitHub Pages site

  @see https://docs.github.com/rest/pages/pages#get-a-apiname-pages-site
  """
  def get_pages(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Page, options)
  end

  @doc """
  Get GitHub Pages build

  @see https://docs.github.com/rest/pages/pages#get-apiname-pages-build
  """
  def get_pages_build(build_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/builds/#{build_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.PageBuild, options)
  end

  @doc """
  Get the status of a GitHub Pages deployment

  @see https://docs.github.com/rest/pages/pages#get-the-status-of-a-github-pages-deployment
  """
  def get_pages_deployment(pages_deployment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/deployments/#{pages_deployment_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.PagesDeploymentStatus, options)
  end

  @doc """
  Get a DNS health check for GitHub Pages

  @see https://docs.github.com/rest/pages/pages#get-a-dns-health-check-for-github-pages
  """
  def get_pages_health_check(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/health"
    body = %{}
    api_call(:get, url, body, Noizu.Github.PagesHealthCheck, options)
  end

  @doc """
  Get the weekly commit count

  @see https://docs.github.com/rest/metrics/statistics#get-the-weekly-commit-count
  """
  def get_participation_stats(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/stats/participation"
    body = %{}
    api_call(:get, url, body, Noizu.Github.ParticipationStats, options)
  end

  @doc """
  Get pull request review protection

  @see https://docs.github.com/rest/branches/branch-protection#get-pull-request-review-protection
  """
  def get_pull_request_review_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_pull_request_reviews"

    body = %{}
    api_call(:get, url, body, Noizu.Github.ProtectedBranchPullRequestReview, options)
  end

  @doc """
  Get the hourly commit count for each day

  @see https://docs.github.com/rest/metrics/statistics#get-the-hourly-commit-count-for-each-day
  """
  def get_punch_card_stats(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/stats/punch_card"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Get a repository README

  @see https://docs.github.com/rest/repos/contents#get-a-repository-readme
  """
  def get_readme(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:ref, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/readme" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.ContentFile, options)
  end

  @doc """
  Get a repository README for a directory

  @see https://docs.github.com/rest/repos/contents#get-a-repository-readme-for-a-directory
  """
  def get_readme_in_directory(dir, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:ref, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/readme/#{dir}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.ContentFile, options)
  end

  @doc """
  Get a release

  @see https://docs.github.com/rest/releases/releases#get-a-release
  """
  def get_release(release_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/#{release_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Release, options)
  end

  @doc """
  Get a release asset

  @see https://docs.github.com/rest/releases/assets#get-a-release-asset
  """
  def get_release_asset(asset_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/assets/#{asset_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.ReleaseAsset, options)
  end

  @doc """
  Get a release by tag name

  @see https://docs.github.com/rest/releases/releases#get-a-release-by-tag-name
  """
  def get_release_by_tag(tag, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/tags/#{tag}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Release, options)
  end

  @doc """
  Get a repository rule suite

  @see https://docs.github.com/rest/repos/rule-suites#get-a-repository-rule-suite
  """
  def get_repo_rule_suite(rule_suite_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/rulesets/rule-suites/#{rule_suite_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RuleSuite, options)
  end

  @doc """
  List repository rule suites

  @see https://docs.github.com/rest/repos/rule-suites#list-repository-rule-suites
  """
  def get_repo_rule_suites(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:ref, options, nil),
            get_field(:time_period, options, nil),
            get_field(:actor_name, options, nil),
            get_field(:rule_suite_result, options, nil),
            get_field(:evaluate_status, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/rulesets/rule-suites" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get a repository ruleset

  @see https://docs.github.com/rest/repos/rules#get-a-repository-ruleset
  """
  def get_repo_ruleset(ruleset_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:includes_parents, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/rulesets/#{ruleset_id}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Get repository ruleset history

  @see https://docs.github.com/rest/repos/rules#get-repository-ruleset-history
  """
  def get_repo_ruleset_history(ruleset_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/rulesets/#{ruleset_id}/history" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.RulesetVersion, options)
  end

  @doc """
  Get repository ruleset version

  @see https://docs.github.com/rest/repos/rules#get-repository-ruleset-version
  """
  def get_repo_ruleset_version(ruleset_id, version_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/rulesets/#{ruleset_id}/history/#{version_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.RulesetVersionWithState, options)
  end

  @doc """
  Get all repository rulesets

  @see https://docs.github.com/rest/repos/rules#get-all-repository-rulesets
  """
  def get_repo_rulesets(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil),
            get_field(:includes_parents, options, nil),
            get_field(:targets, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/rulesets" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.RepositoryRuleset, options)
  end

  @doc """
  Get status checks protection

  @see https://docs.github.com/rest/branches/branch-protection#get-status-checks-protection
  """
  def get_status_checks_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks"

    body = %{}
    api_call(:get, url, body, Noizu.Github.StatusCheckPolicy, options)
  end

  @doc """
  Get teams with access to the protected branch

  @see https://docs.github.com/rest/branches/branch-protection#get-teams-with-access-to-the-protected-branch
  """
  def get_teams_with_access_to_protected_branch(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/teams"

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Team, options)
  end

  @doc """
  Get top referral paths

  @see https://docs.github.com/rest/metrics/traffic#get-top-referral-paths
  """
  def get_top_paths(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/traffic/popular/paths"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.ContentTraffic, options)
  end

  @doc """
  Get top referral sources

  @see https://docs.github.com/rest/metrics/traffic#get-top-referral-sources
  """
  def get_top_referrers(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/traffic/popular/referrers"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.ReferrerTraffic, options)
  end

  @doc """
  Get users with access to the protected branch

  @see https://docs.github.com/rest/branches/branch-protection#get-users-with-access-to-the-protected-branch
  """
  def get_users_with_access_to_protected_branch(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/users"

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.SimpleUser, options)
  end

  @doc """
  Get page views

  @see https://docs.github.com/rest/metrics/traffic#get-page-views
  """
  def get_views(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/traffic/views" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.ViewTraffic, options)
  end

  @doc """
  Get a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#get-a-repository-webhook
  """
  def get_webhook(hook_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Hook, options)
  end

  @doc """
  Get a webhook configuration for a repository

  @see https://docs.github.com/rest/repos/webhooks#get-a-webhook-configuration-for-a-repository
  """
  def get_webhook_config_for_repo(hook_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/config"
    body = %{}
    api_call(:get, url, body, Noizu.Github.WebhookConfig, options)
  end

  @doc """
  Get a delivery for a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#get-a-delivery-for-a-repository-webhook
  """
  def get_webhook_delivery(hook_id, delivery_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/deliveries/#{delivery_id}"
    body = %{}
    api_call(:get, url, body, Noizu.Github.HookDelivery, options)
  end

  @doc """
  List repository activities

  @see https://docs.github.com/rest/repos/repos#list-repository-activities
  """
  def list_activities(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:direction, options, nil),
            get_field(:per_page, options, nil),
            get_field(:before, options, nil),
            get_field(:after, options, nil),
            get_field(:ref, options, nil),
            get_field(:actor, options, nil),
            get_field(:time_period, options, nil),
            get_field(:activity_type, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/activity" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Activity, options)
  end

  @doc """
  List attestations

  @see https://docs.github.com/rest/repos/attestations#list-attestations
  """
  def list_attestations(subject_digest, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:before, options, nil),
            get_field(:after, options, nil),
            get_field(:predicate_type, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/attestations/#{subject_digest}" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Get all autolinks of a repository

  @see https://docs.github.com/rest/repos/autolinks#get-all-autolinks-of-a-repository
  """
  def list_autolinks(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/autolinks"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Autolink, options)
  end

  @doc """
  List branches

  @see https://docs.github.com/rest/branches/branches#list-branches
  """
  def list_branches(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:protected, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/branches" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.ShortBranch, options)
  end

  @doc """
  List branches for HEAD commit

  @see https://docs.github.com/rest/commits/commits#list-branches-for-head-commit
  """
  def list_branches_for_head_commit(commit_sha, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/commits/#{commit_sha}/branches-where-head"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.BranchShort, options)
  end

  @doc """
  List repository collaborators

  @see https://docs.github.com/rest/collaborators/collaborators#list-repository-collaborators
  """
  def list_collaborators(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:affiliation, options, nil),
            get_field(:permission, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/collaborators" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Collaborator, options)
  end

  @doc """
  List commit comments

  @see https://docs.github.com/rest/commits/comments#list-commit-comments
  """
  def list_comments_for_commit(commit_sha, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits/#{commit_sha}/comments" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.CommitComment, options)
  end

  @doc """
  List commit comments for a repository

  @see https://docs.github.com/rest/commits/comments#list-commit-comments-for-a-repository
  """
  def list_commit_comments_for_repo(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/comments" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.CommitComment, options)
  end

  @doc """
  List commit statuses for a reference

  @see https://docs.github.com/rest/commits/statuses#list-commit-statuses-for-a-reference
  """
  def list_commit_statuses_for_ref(ref, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits/#{ref}/statuses" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Status, options)
  end

  @doc """
  List commits

  @see https://docs.github.com/rest/commits/commits#list-commits
  """
  def list_commits(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:sha, options, nil),
            get_field(:path, options, nil),
            get_field(:author, options, nil),
            get_field(:committer, options, nil),
            get_field(:since, options, nil),
            get_field(:until, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Commit, options)
  end

  @doc """
  List repository contributors

  @see https://docs.github.com/rest/repos/repos#list-repository-contributors
  """
  def list_contributors(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:anon, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/contributors" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Contributor, options)
  end

  @doc """
  List custom deployment rule integrations available for an environment

  @see https://docs.github.com/rest/deployments/protection-rules#list-custom-deployment-rule-integrations-available-for-an-environment
  """
  def list_custom_deployment_rule_integrations(environment_name, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:page, options, nil),
            get_field(:per_page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")

        github_base() <>
          "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment_protection_rules/apps" <>
          qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  List deploy keys

  @see https://docs.github.com/rest/deploy-keys/deploy-keys#list-deploy-keys
  """
  def list_deploy_keys(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/keys" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.DeployKey, options)
  end

  @doc """
  List deployment branch policies

  @see https://docs.github.com/rest/deployments/branch-policies#list-deployment-branch-policies
  """
  def list_deployment_branch_policies(environment_name, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")

        github_base() <>
          "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment-branch-policies" <>
          qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  List deployment statuses

  @see https://docs.github.com/rest/deployments/statuses#list-deployment-statuses
  """
  def list_deployment_statuses(deployment_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/deployments/#{deployment_id}/statuses" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.DeploymentStatus, options)
  end

  @doc """
  List deployments

  @see https://docs.github.com/rest/deployments/deployments#list-deployments
  """
  def list_deployments(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:sha, options, nil),
            get_field(:ref, options, nil),
            get_field(:task, options, nil),
            get_field(:environment, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/deployments" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Deployment, options)
  end

  @doc """
  List repositories for the authenticated user

  @see https://docs.github.com/rest/repos/repos#list-repositories-for-the-authenticated-user
  """
  def list_for_authenticated_user(options \\ nil) do
    url =
      (
        query =
          [
            get_field(:visibility, options, nil),
            get_field(:affiliation, options, nil),
            get_field(:type, options, nil),
            get_field(:sort, options, nil),
            get_field(:direction, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil),
            get_field(:since, options, nil),
            get_field(:before, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/user/repos" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Repository, options)
  end

  @doc """
  List organization repositories

  @see https://docs.github.com/rest/repos/repos#list-organization-repositories
  """
  def list_for_org(org, options \\ nil) do
    url =
      (
        query =
          [
            get_field(:type, options, nil),
            get_field(:sort, options, nil),
            get_field(:direction, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/orgs/#{org}/repos" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.MinimalRepository, options)
  end

  @doc """
  List repositories for a user

  @see https://docs.github.com/rest/repos/repos#list-repositories-for-a-user
  """
  def list_for_user(username, options \\ nil) do
    url =
      (
        query =
          [
            get_field(:type, options, nil),
            get_field(:sort, options, nil),
            get_field(:direction, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/users/#{username}/repos" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.MinimalRepository, options)
  end

  @doc """
  List forks

  @see https://docs.github.com/rest/repos/forks#list-forks
  """
  def list_forks(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:sort, options, nil),
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/forks" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.MinimalRepository, options)
  end

  @doc """
  List repository invitations

  @see https://docs.github.com/rest/collaborators/invitations#list-repository-invitations
  """
  def list_invitations(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/invitations" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.RepositoryInvitation, options)
  end

  @doc """
  List repository invitations for the authenticated user

  @see https://docs.github.com/rest/collaborators/invitations#list-repository-invitations-for-the-authenticated-user
  """
  def list_invitations_for_authenticated_user(options \\ nil) do
    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/user/repository_invitations" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.RepositoryInvitation, options)
  end

  @doc """
  List issue types for a repository

  @see https://docs.github.com/rest/repos/issue-types#list-issue-types-for-a-repository
  """
  def list_issue_types(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/issue-types"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.IssueType, options)
  end

  @doc """
  List repository languages

  @see https://docs.github.com/rest/repos/repos#list-repository-languages
  """
  def list_languages(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/languages"
    body = %{}
    api_call(:get, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  List GitHub Pages builds

  @see https://docs.github.com/rest/pages/pages#list-apiname-pages-builds
  """
  def list_pages_builds(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/pages/builds" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.PageBuild, options)
  end

  @doc """
  List public repositories

  @see https://docs.github.com/rest/repos/repos#list-public-repositories
  """
  def list_public(options \\ nil) do
    url =
      (
        query =
          [
            get_field(:since, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repositories" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.MinimalRepository, options)
  end

  @doc """
  List pull requests associated with a commit

  @see https://docs.github.com/rest/commits/commits#list-pull-requests-associated-with-a-commit
  """
  def list_pull_requests_associated_with_commit(commit_sha, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/commits/#{commit_sha}/pulls" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.PullRequestSimple, options)
  end

  @doc """
  List release assets

  @see https://docs.github.com/rest/releases/assets#list-release-assets
  """
  def list_release_assets(release_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/releases/#{release_id}/assets" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.ReleaseAsset, options)
  end

  @doc """
  List releases

  @see https://docs.github.com/rest/releases/releases#list-releases
  """
  def list_releases(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/releases" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Release, options)
  end

  @doc """
  List repository tags

  @see https://docs.github.com/rest/repos/repos#list-repository-tags
  """
  def list_tags(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/tags" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Tag, options)
  end

  @doc """
  List repository teams

  @see https://docs.github.com/rest/repos/repos#list-repository-teams
  """
  def list_teams(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/teams" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Team, options)
  end

  @doc """
  List deliveries for a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#list-deliveries-for-a-repository-webhook
  """
  def list_webhook_deliveries(hook_id, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:cursor, options, nil),
            get_field(:status, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/deliveries" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.HookDeliveryItem, options)
  end

  @doc """
  List repository webhooks

  @see https://docs.github.com/rest/repos/webhooks#list-repository-webhooks
  """
  def list_webhooks(options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:per_page, options, nil),
            get_field(:page, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/hooks" <> qs
      )

    body = %{}
    api_call(:get, url, body, Noizu.Github.Collection.Hook, options)
  end

  @doc """
  Merge a branch

  @see https://docs.github.com/rest/branches/branches#merge-a-branch
  """
  def merge(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/merges"
    body = body
    api_call(:post, url, body, Noizu.Github.Commit, options)
  end

  @doc """
  Sync a fork branch with the upstream repository

  @see https://docs.github.com/rest/branches/branches#sync-a-fork-branch-with-the-upstream-repository
  """
  def merge_upstream(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/merge-upstream"
    body = body
    api_call(:post, url, body, Noizu.Github.MergedUpstream, options)
  end

  @doc """
  Ping a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#ping-a-repository-webhook
  """
  def ping_webhook(hook_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/pings"
    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Redeliver a delivery for a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#redeliver-a-delivery-for-a-repository-webhook
  """
  def redeliver_webhook_delivery(hook_id, delivery_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/hooks/#{hook_id}/deliveries/#{delivery_id}/attempts"

    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Remove app access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#remove-app-access-restrictions
  """
  def remove_app_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/apps"

    body = body
    api_call(:delete, url, body, Noizu.Github.Collection.Integration, options)
  end

  @doc """
  Remove a repository collaborator

  @see https://docs.github.com/rest/collaborators/collaborators#remove-a-repository-collaborator
  """
  def remove_collaborator(username, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/collaborators/#{username}"
    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Remove status check contexts

  @see https://docs.github.com/rest/branches/branch-protection#remove-status-check-contexts
  """
  def remove_status_check_contexts(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks/contexts"

    body = body
    api_call(:delete, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Remove status check protection

  @see https://docs.github.com/rest/branches/branch-protection#remove-status-check-protection
  """
  def remove_status_check_protection(branch, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks"

    body = %{}
    api_call(:delete, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Remove team access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#remove-team-access-restrictions
  """
  def remove_team_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/teams"

    body = body
    api_call(:delete, url, body, Noizu.Github.Collection.Team, options)
  end

  @doc """
  Remove user access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#remove-user-access-restrictions
  """
  def remove_user_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/users"

    body = body
    api_call(:delete, url, body, Noizu.Github.Collection.SimpleUser, options)
  end

  @doc """
  Rename a branch

  @see https://docs.github.com/rest/branches/branches#rename-a-branch
  """
  def rename_branch(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/rename"
    body = body
    api_call(:post, url, body, Noizu.Github.BranchWithProtection, options)
  end

  @doc """
  Replace all repository topics

  @see https://docs.github.com/rest/repos/repos#replace-all-repository-topics
  """
  def replace_all_topics(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/topics"
    body = body
    api_call(:put, url, body, Noizu.Github.Topic, options)
  end

  @doc """
  Request a GitHub Pages build

  @see https://docs.github.com/rest/pages/pages#request-a-apiname-pages-build
  """
  def request_pages_build(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages/builds"
    body = body
    api_call(:post, url, body, Noizu.Github.PageBuildStatus, options)
  end

  @doc """
  Set admin branch protection

  @see https://docs.github.com/rest/branches/branch-protection#set-admin-branch-protection
  """
  def set_admin_branch_protection(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/enforce_admins"
    body = body
    api_call(:post, url, body, Noizu.Github.ProtectedBranchAdminEnforced, options)
  end

  @doc """
  Set app access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#set-app-access-restrictions
  """
  def set_app_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/apps"

    body = body
    api_call(:put, url, body, Noizu.Github.Collection.Integration, options)
  end

  @doc """
  Set status check contexts

  @see https://docs.github.com/rest/branches/branch-protection#set-status-check-contexts
  """
  def set_status_check_contexts(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks/contexts"

    body = body
    api_call(:put, url, body, Noizu.Github.Collection, options)
  end

  @doc """
  Set team access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#set-team-access-restrictions
  """
  def set_team_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/teams"

    body = body
    api_call(:put, url, body, Noizu.Github.Collection.Team, options)
  end

  @doc """
  Set user access restrictions

  @see https://docs.github.com/rest/branches/branch-protection#set-user-access-restrictions
  """
  def set_user_access_restrictions(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection/restrictions/users"

    body = body
    api_call(:put, url, body, Noizu.Github.Collection.SimpleUser, options)
  end

  @doc """
  Test the push repository webhook

  @see https://docs.github.com/rest/repos/webhooks#test-the-push-repository-webhook
  """
  def test_push_webhook(hook_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/tests"
    body = body
    api_call(:post, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Transfer a repository

  @see https://docs.github.com/rest/repos/repos#transfer-a-repository
  """
  def transfer(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/transfer"
    body = body
    api_call(:post, url, body, Noizu.Github.MinimalRepository, options)
  end

  @doc """
  Update a repository

  @see https://docs.github.com/rest/repos/repos#update-a-repository
  """
  def update(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}"
    body = body
    api_call(:patch, url, body, Noizu.Github.FullRepository, options)
  end

  @doc """
  Update branch protection

  @see https://docs.github.com/rest/branches/branch-protection#update-branch-protection
  """
  def update_branch_protection(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/branches/#{branch}/protection"
    body = body
    api_call(:put, url, body, Noizu.Github.ProtectedBranch, options)
  end

  @doc """
  Update a commit comment

  @see https://docs.github.com/rest/commits/comments#update-a-commit-comment
  """
  def update_commit_comment(comment_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/comments/#{comment_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.CommitComment, options)
  end

  @doc """
  Update a deployment branch policy

  @see https://docs.github.com/rest/deployments/branch-policies#update-a-deployment-branch-policy
  """
  def update_deployment_branch_policy(environment_name, branch_policy_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/environments/#{environment_name}/deployment-branch-policies/#{branch_policy_id}"

    body = body
    api_call(:put, url, body, Noizu.Github.DeploymentBranchPolicy, options)
  end

  @doc """
  Update information about a GitHub Pages site

  @see https://docs.github.com/rest/pages/pages#update-information-about-a-apiname-pages-site
  """
  def update_information_about_pages_site(body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/pages"
    body = body
    api_call(:put, url, body, Noizu.Github.Raw, options)
  end

  @doc """
  Update a repository invitation

  @see https://docs.github.com/rest/collaborators/invitations#update-a-repository-invitation
  """
  def update_invitation(invitation_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/invitations/#{invitation_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.RepositoryInvitation, options)
  end

  @doc """
  Update an organization repository ruleset

  @see https://docs.github.com/rest/orgs/rules#update-an-organization-repository-ruleset
  """
  def update_org_ruleset(org, ruleset_id, body, options \\ nil) do
    url = github_base() <> "/orgs/#{org}/rulesets/#{ruleset_id}"
    body = body
    api_call(:put, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Update pull request review protection

  @see https://docs.github.com/rest/branches/branch-protection#update-pull-request-review-protection
  """
  def update_pull_request_review_protection(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_pull_request_reviews"

    body = body
    api_call(:patch, url, body, Noizu.Github.ProtectedBranchPullRequestReview, options)
  end

  @doc """
  Update a release

  @see https://docs.github.com/rest/releases/releases#update-a-release
  """
  def update_release(release_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/#{release_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.Release, options)
  end

  @doc """
  Update a release asset

  @see https://docs.github.com/rest/releases/assets#update-a-release-asset
  """
  def update_release_asset(asset_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/releases/assets/#{asset_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.ReleaseAsset, options)
  end

  @doc """
  Update a repository ruleset

  @see https://docs.github.com/rest/repos/rules#update-a-repository-ruleset
  """
  def update_repo_ruleset(ruleset_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/rulesets/#{ruleset_id}"
    body = body
    api_call(:put, url, body, Noizu.Github.RepositoryRuleset, options)
  end

  @doc """
  Update status check protection

  @see https://docs.github.com/rest/branches/branch-protection#update-status-check-protection
  """
  def update_status_check_protection(branch, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      github_base() <>
        "/repos/#{owner}/#{repo}/branches/#{branch}/protection/required_status_checks"

    body = body
    api_call(:patch, url, body, Noizu.Github.StatusCheckPolicy, options)
  end

  @doc """
  Update a repository webhook

  @see https://docs.github.com/rest/repos/webhooks#update-a-repository-webhook
  """
  def update_webhook(hook_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}"
    body = body
    api_call(:patch, url, body, Noizu.Github.Hook, options)
  end

  @doc """
  Update a webhook configuration for a repository

  @see https://docs.github.com/rest/repos/webhooks#update-a-webhook-configuration-for-a-repository
  """
  def update_webhook_config_for_repo(hook_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)
    url = github_base() <> "/repos/#{owner}/#{repo}/hooks/#{hook_id}/config"
    body = body
    api_call(:patch, url, body, Noizu.Github.WebhookConfig, options)
  end

  @doc """
  Upload a release asset

  @see https://docs.github.com/rest/releases/assets#upload-a-release-asset
  """
  def upload_release_asset(release_id, body, options \\ nil) do
    owner = repo_owner(options)
    repo = repo_name(options)

    url =
      (
        query =
          [
            get_field(:name, options, nil),
            get_field(:label, options, nil)
          ]
          |> Enum.filter(& &1)

        qs = if query == [], do: "", else: "?" <> Enum.join(query, "&")
        github_base() <> "/repos/#{owner}/#{repo}/releases/#{release_id}/assets" <> qs
      )

    body = body
    api_call(:post, url, body, Noizu.Github.ReleaseAsset, options)
  end
end