import subprocess

import osc.commandline_git


class PullRequestCheckoutCommand(osc.commandline_git.GitObsCommand):
    """
    Check out a pull request
    """

    name = "checkout"
    parent = "PullRequestCommand"

    def init_arguments(self):
        self.add_argument(
            "pull",
            type=int,
            help="Number of the pull request",
        )
        self.add_argument(
            "-f",
            "--force",
            action="store_true",
            help="Reset the existing local branch to the latest state of the pull request",
        )

    def run(self, args):
        from osc import gitea_api

        self.print_gitea_settings()

        git = gitea_api.Git(".")
        owner, repo = git.get_owner_repo()

        pr = gitea_api.PullRequest.get(self.gitea_conn, owner, repo, args.pull).json()

        head_ssh_url = pr["head"]["repo"]["ssh_url"]
        head_owner = pr["head"]["repo"]["owner"]["login"]
        head_branch = pr["head"]["ref"]

        try:
            git.add_remote(head_owner, head_ssh_url)
        except subprocess.CalledProcessError as e:
            # TODO: check if the remote url matches
            if e.returncode != 3:
                # returncode 3 means that the remote exists; see `man git-remote`
                raise
        git.fetch(head_owner)

        local_branch = git.fetch_pull_request(args.pull, force=args.force)

        # LFS data may not be accessible in the "origin" remote, we need to allow searching in all remotes
        git.set_config("lfs.remote.searchall", "1")

        # configure branch for `git push`
        git.set_config(f"branch.{local_branch}.remote", head_owner)
        git.set_config(f"branch.{local_branch}.pushRemote", head_owner)
        git.set_config(f"branch.{local_branch}.merge", f"refs/heads/{head_branch}")

        # allow `git push` with no arguments to push to a remote branch that is named differently than the local branch
        git.set_config("push.default", "upstream")

        git.switch(local_branch)
