pub mod archive;
pub mod blame;
pub mod blob;
pub mod branch;
pub mod branch_protection;
pub mod commit;
pub mod contributors;
pub mod diff;
pub mod init;
pub mod refs;
pub mod repo;
pub mod star;
pub mod tag;
pub mod tree;
pub mod watch;
pub mod webhook;

use actix_web::web;

pub fn init_git_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::scope("/repos/{namespace}/{repo}/git")
            .route("/archive", web::get().to(archive::git_archive))
            .route("/archive/list", web::get().to(archive::git_archive_list))
            .route(
                "/archive/summary",
                web::get().to(archive::git_archive_summary),
            )
            .route(
                "/archive/cached",
                web::get().to(archive::git_archive_cached),
            )
            .route(
                "/archive/invalidate",
                web::get().to(archive::git_archive_invalidate),
            )
            .route(
                "/archive/invalidate-all/{commit_oid}",
                web::get().to(archive::git_archive_invalidate_all),
            )
            // blame
            .route(
                "/blame/{commit_oid}/{tail:.*}",
                web::get().to(blame::git_blame_file),
            )
            // blob
            .route("/blob", web::post().to(blob::git_blob_create))
            .route("/blob/{oid}", web::get().to(blob::git_blob_get))
            .route("/blob/{oid}/exists", web::get().to(blob::git_blob_exists))
            .route(
                "/blob/{oid}/is-binary",
                web::get().to(blob::git_blob_is_binary),
            )
            .route("/blob/{oid}/content", web::get().to(blob::git_blob_content))
            .route("/blob/{oid}/size", web::get().to(blob::git_blob_size))
            .route("/readme", web::get().to(blob::git_readme))
            // branch
            .route("/branches", web::get().to(branch::git_branch_list))
            .route(
                "/branches/summary",
                web::get().to(branch::git_branch_summary),
            )
            .route("/branches", web::post().to(branch::git_branch_create))
            // NOTE: /branches/current MUST be before /branches/{name} to avoid being shadowed
            .route(
                "/branches/current",
                web::get().to(branch::git_branch_current),
            )
            .route("/branches/{name}", web::get().to(branch::git_branch_get))
            .route(
                "/branches/{name}",
                web::delete().to(branch::git_branch_delete),
            )
            .route(
                "/branches/{name}/exists",
                web::get().to(branch::git_branch_exists),
            )
            .route(
                "/branches/{name}/is-head",
                web::get().to(branch::git_branch_is_head),
            )
            .route(
                "/branches/{name}/upstream",
                web::get().to(branch::git_branch_upstream),
            )
            .route(
                "/branches/{name}/tracking-difference",
                web::get().to(branch::git_branch_tracking_difference),
            )
            .route(
                "/branches/remote/{name}",
                web::delete().to(branch::git_branch_delete_remote),
            )
            .route(
                "/branches/rename",
                web::patch().to(branch::git_branch_rename),
            )
            .route("/branches/move", web::patch().to(branch::git_branch_move))
            .route(
                "/branches/upstream",
                web::patch().to(branch::git_branch_set_upstream),
            )
            .route("/branches/diff", web::get().to(branch::git_branch_diff))
            .route(
                "/branches/is-detached",
                web::get().to(branch::git_branch_is_detached),
            )
            .route(
                "/branches/is-merged",
                web::get().to(branch::git_branch_is_merged),
            )
            .route(
                "/branches/merge-base",
                web::get().to(branch::git_branch_merge_base),
            )
            .route(
                "/branches/is-ancestor",
                web::get().to(branch::git_branch_is_ancestor),
            )
            .route(
                "/branches/fast-forward/{target}",
                web::post().to(branch::git_branch_fast_forward),
            )
            .route(
                "/branches/is-conflicted",
                web::get().to(branch::git_branch_is_conflicted),
            )
            // commit
            .route("/commits", web::get().to(commit::git_commit_log))
            .route("/commits/count", web::get().to(commit::git_commit_count))
            .route("/commits", web::post().to(commit::git_commit_create))
            .route("/commits/graph", web::get().to(commit::git_commit_graph))
            .route(
                "/commits/graph-react",
                web::get().to(commit::git_commit_graph_react),
            )
            .route("/commits/walk", web::get().to(commit::git_commit_walk))
            .route(
                "/commits/resolve/{rev}",
                web::get().to(commit::git_commit_resolve_rev),
            )
            .route("/commits/{oid}", web::get().to(commit::git_commit_get))
            .route("/commits/{oid}", web::patch().to(commit::git_commit_amend))
            .route(
                "/commits/{oid}/exists",
                web::get().to(commit::git_commit_exists),
            )
            .route(
                "/commits/{oid}/is-commit",
                web::get().to(commit::git_commit_is_commit),
            )
            .route(
                "/commits/{oid}/message",
                web::get().to(commit::git_commit_message),
            )
            .route(
                "/commits/{oid}/summary",
                web::get().to(commit::git_commit_summary),
            )
            .route(
                "/commits/{oid}/short-id",
                web::get().to(commit::git_commit_short_id),
            )
            .route(
                "/commits/{oid}/author",
                web::get().to(commit::git_commit_author),
            )
            .route(
                "/commits/{oid}/tree-id",
                web::get().to(commit::git_commit_tree_id),
            )
            .route(
                "/commits/{oid}/parent-count",
                web::get().to(commit::git_commit_parent_count),
            )
            .route(
                "/commits/{oid}/parent-ids",
                web::get().to(commit::git_commit_parent_ids),
            )
            .route(
                "/commits/{oid}/parent/{index}",
                web::get().to(commit::git_commit_parent),
            )
            .route(
                "/commits/{oid}/first-parent",
                web::get().to(commit::git_commit_first_parent),
            )
            .route(
                "/commits/{oid}/is-merge",
                web::get().to(commit::git_commit_is_merge),
            )
            .route(
                "/commits/{oid}/refs",
                web::get().to(commit::git_commit_refs),
            )
            .route(
                "/commits/branches",
                web::get().to(commit::git_commit_branches),
            )
            .route("/commits/tags", web::get().to(commit::git_commit_tags))
            .route(
                "/commits/{oid}/is-tip",
                web::get().to(commit::git_commit_is_tip),
            )
            .route(
                "/commits/{oid}/ref-count",
                web::get().to(commit::git_commit_ref_count),
            )
            .route("/commits/reflog", web::get().to(commit::git_commit_reflog))
            .route(
                "/commits/{oid}/ancestors",
                web::get().to(commit::git_commit_ancestors),
            )
            .route(
                "/commits/{oid}/descendants",
                web::get().to(commit::git_commit_descendants),
            )
            .route(
                "/commits/{oid}/cherry-pick",
                web::post().to(commit::git_commit_cherry_pick),
            )
            .route(
                "/commits/{oid}/cherry-pick/abort",
                web::post().to(commit::git_commit_cherry_pick_abort),
            )
            .route(
                "/commits/{oid}/revert",
                web::post().to(commit::git_commit_revert),
            )
            .route(
                "/commits/{oid}/revert/abort",
                web::post().to(commit::git_commit_revert_abort),
            )
            // contributors
            .route(
                "/contributors",
                web::get().to(contributors::git_contributors),
            )
            // diff
            .route("/diff", web::get().to(diff::git_diff_tree_to_tree))
            .route(
                "/diff/commit/{commit}",
                web::get().to(diff::git_diff_commit_to_workdir),
            )
            .route(
                "/diff/commit/{commit}/index",
                web::get().to(diff::git_diff_commit_to_index),
            )
            .route(
                "/diff/workdir",
                web::get().to(diff::git_diff_workdir_to_index),
            )
            .route("/diff/index", web::get().to(diff::git_diff_index_to_tree))
            .route("/diff/stats", web::get().to(diff::git_diff_stats))
            .route("/diff/patch-id", web::get().to(diff::git_diff_patch_id))
            .route(
                "/diff/side-by-side",
                web::get().to(diff::git_diff_side_by_side),
            )
            // refs
            .route("/refs", web::get().to(refs::git_ref_list))
            .route("/refs", web::post().to(refs::git_ref_create))
            .route("/refs/{name}", web::get().to(refs::git_ref_get))
            .route("/refs/{name}", web::delete().to(refs::git_ref_delete))
            .route("/refs/rename", web::patch().to(refs::git_ref_rename))
            .route("/refs/update", web::patch().to(refs::git_ref_update))
            .route("/refs/{name}/exists", web::get().to(refs::git_ref_exists))
            .route("/refs/{name}/target", web::get().to(refs::git_ref_target))
            // repo (description, config, merge)
            .route("/description", web::get().to(repo::git_description_get))
            .route("/description", web::put().to(repo::git_description_set))
            .route(
                "/description",
                web::delete().to(repo::git_description_reset),
            )
            .route(
                "/description/exists",
                web::get().to(repo::git_description_exists),
            )
            .route("/git", web::patch().to(repo::git_update_repo))
            .route("/config/entries", web::get().to(repo::git_config_entries))
            .route("/config/{key}", web::get().to(repo::git_config_get))
            .route("/config/{key}", web::put().to(repo::git_config_set))
            .route("/config/{key}", web::delete().to(repo::git_config_delete))
            .route("/config/{key}/has", web::get().to(repo::git_config_has))
            .route(
                "/merge/analysis/{their_oid}",
                web::get().to(repo::git_merge_analysis),
            )
            .route(
                "/merge/analysis/{ref_name}/{their_oid}",
                web::get().to(repo::git_merge_analysis_for_ref),
            )
            .route(
                "/merge/base/{oid1}/{oid2}",
                web::get().to(repo::git_merge_base),
            )
            .route("/merge/commits", web::post().to(repo::git_merge_commits))
            .route("/merge/trees", web::post().to(repo::git_merge_trees))
            .route("/merge/abort", web::post().to(repo::git_merge_abort))
            .route(
                "/merge/in-progress",
                web::get().to(repo::git_merge_is_in_progress),
            )
            .route("/merge/heads", web::get().to(repo::git_mergehead_list))
            .route(
                "/merge/is-conflicted",
                web::get().to(repo::git_merge_is_conflicted),
            )
            // star
            .route("/star", web::post().to(star::git_star))
            .route("/star", web::delete().to(star::git_unstar))
            .route("/star/is-starred", web::get().to(star::git_is_starred))
            .route("/star/count", web::get().to(star::git_star_count))
            .route("/star/users", web::get().to(star::git_star_user_list))
            // branch protection
            .route(
                "/branch-protections",
                web::get().to(branch_protection::branch_protection_list),
            )
            .route(
                "/branch-protections",
                web::post().to(branch_protection::branch_protection_create),
            )
            .route(
                "/branch-protections/check-approvals",
                web::get().to(branch_protection::branch_protection_check_approvals),
            )
            .route(
                "/branch-protections/{id}",
                web::get().to(branch_protection::branch_protection_get),
            )
            .route(
                "/branch-protections/{id}",
                web::patch().to(branch_protection::branch_protection_update),
            )
            .route(
                "/branch-protections/{id}",
                web::delete().to(branch_protection::branch_protection_delete),
            )
            // tag
            .route("/tags", web::get().to(tag::git_tag_list))
            .route("/tags/names", web::get().to(tag::git_tag_list_names))
            .route("/tags/summary", web::get().to(tag::git_tag_summary))
            .route("/tags/count", web::get().to(tag::git_tag_count))
            .route("/tags", web::post().to(tag::git_tag_create))
            .route(
                "/tags/lightweight",
                web::post().to(tag::git_tag_create_lightweight),
            )
            .route("/tags/rename", web::patch().to(tag::git_tag_rename))
            .route(
                "/tags/message",
                web::patch().to(tag::git_tag_update_message),
            )
            .route("/tags/{name}", web::get().to(tag::git_tag_get))
            .route("/tags/{name}", web::delete().to(tag::git_tag_delete))
            .route("/tags/{name}/exists", web::get().to(tag::git_tag_exists))
            .route("/tags/{name}/target", web::get().to(tag::git_tag_target))
            .route(
                "/tags/{name}/is-annotated",
                web::get().to(tag::git_tag_is_annotated),
            )
            .route("/tags/{name}/message", web::get().to(tag::git_tag_message))
            .route("/tags/{name}/tagger", web::get().to(tag::git_tag_tagger))
            // tree
            .route("/tree/{oid}", web::get().to(tree::git_tree_get))
            .route("/tree/{oid}/exists", web::get().to(tree::git_tree_exists))
            .route("/tree/{oid}/list", web::get().to(tree::git_tree_list))
            .route(
                "/tree/{oid}/entry/{index}",
                web::get().to(tree::git_tree_entry),
            )
            .route(
                "/tree/{oid}/entry-by-path",
                web::get().to(tree::git_tree_entry_by_path),
            )
            .route(
                "/tree/{commit}/commit-entry-by-path",
                web::get().to(tree::git_tree_entry_by_commit_path),
            )
            .route(
                "/tree/{oid}/entry-count",
                web::get().to(tree::git_tree_entry_count),
            )
            .route(
                "/tree/{oid}/is-empty",
                web::get().to(tree::git_tree_is_empty),
            )
            .route("/tree/diff-stats", web::get().to(tree::git_tree_diffstats))
            // watch
            .route("/watch", web::post().to(watch::git_watch))
            .route("/watch", web::delete().to(watch::git_unwatch))
            .route("/watch/is-watched", web::get().to(watch::git_is_watched))
            .route("/watch/count", web::get().to(watch::git_watch_count))
            .route("/watch/users", web::get().to(watch::git_watch_user_list))
            // webhook
            .route("/webhooks", web::get().to(webhook::git_webhook_list))
            .route("/webhooks", web::post().to(webhook::git_webhook_create))
            .route(
                "/webhooks/{webhook_id}",
                web::get().to(webhook::git_webhook_get),
            )
            .route(
                "/webhooks/{webhook_id}",
                web::patch().to(webhook::git_webhook_update),
            )
            .route(
                "/webhooks/{webhook_id}",
                web::delete().to(webhook::git_webhook_delete),
            ),
    );
}

pub fn init_git_toplevel_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(web::scope("/git").route("/is-repo/{path}", web::get().to(init::git_is_repo)));
}
