# Path: gg/main.py
# class Config:
#     def __init__(self):
#         self.verbose = False  # default
#         self.configfile = DEFAULT_CONFIGFILE
#         try:
#             self.repo = get_repo()
#         except git.InvalidGitRepositoryError as exception:
#             error_out(f"{exception.args[0]} is not a git repository")
# 
# Path: gg/builtins/getback/gg_getback.py
# @cli.command()
# @click.option("-f", "--force", is_flag=True, default=False)
# @pass_config
# def getback(config, force=False):
#     """Goes back to the default branch, deletes the current branch locally
#     and remotely."""
#     repo = config.repo
# 
#     state = read(config.configfile)
#     origin_name = state.get("ORIGIN_NAME", "origin")
#     default_branch = get_default_branch(repo, origin_name)
#     active_branch = repo.active_branch
#     if active_branch.name == default_branch:
#         error_out(f"You're already on the {default_branch} branch.")
# 
#     if repo.is_dirty():
#         error_out(
#             'Repo is "dirty". ({})'.format(
#                 ", ".join([repr(x.b_path) for x in repo.index.diff(None)])
#             )
#         )
# 
#     branch_name = active_branch.name
# 
#     upstream_remote = None
#     fork_remote = None
#     for remote in repo.remotes:
#         if remote.name == origin_name:
#             # remote.pull()
#             upstream_remote = remote
#             break
#     if not upstream_remote:
#         error_out("No remote called {!r} found".format(origin_name))
# 
#     # Check out default branch
#     repo.heads[default_branch].checkout()
#     upstream_remote.pull(repo.heads[default_branch])
# 
#     # Is this one of the merged branches?!
#     # XXX I don't know how to do this "natively" with GitPython.
#     merged_branches = [
#         x.strip()
#         for x in repo.git.branch("--merged").splitlines()
#         if x.strip() and not x.strip().startswith("*")
#     ]
#     was_merged = branch_name in merged_branches
#     certain = was_merged or force
#     if not certain:
#         # Need to ask the user.
#         # XXX This is where we could get smart and compare this branch
#         # with the default branch.
#         certain = (
#             input("Are you certain {} is actually merged? [Y/n] ".format(branch_name))
#             .lower()
#             .strip()
#             != "n"
#         )
#     if not certain:
#         return 1
# 
#     if was_merged:
#         repo.git.branch("-d", branch_name)
#     else:
#         repo.git.branch("-D", branch_name)
# 
#     fork_remote = None
#     for remote in repo.remotes:
#         if remote.name == state.get("FORK_NAME"):
#             fork_remote = remote
#             break
#     if fork_remote:
#         fork_remote.push(":" + branch_name)
#         info_out("Remote branch on fork deleted too.")


import json
import os
import tempfile
import shutil
import pytest
import requests_mock
from click.testing import CliRunner
from gg.main import Config
from gg.builtins.getback.gg_getback import getback
    with requests_mock.mock() as m:
        yield m


@pytest.yield_fixture
def temp_configfile():
    tmp_dir = tempfile.mkdtemp("gg-start")
    fp = os.path.join(tmp_dir, "state.json")
    with open(fp, "w") as f:
        json.dump({}, f)
    yield fp
    shutil.rmtree(tmp_dir)


def test_getback(temp_configfile, mocker):
    mocked_git = mocker.patch("git.Repo")
    mocked_git().working_dir = "gg-start-test"
    active_branch = mocker.MagicMock()
    mocked_git().active_branch = active_branch
    mocked_remote = mocker.MagicMock()
    mocked_remote.name = "origin"
    mocked_git().remotes.__iter__.return_value = [mocked_remote]
    mocked_git().is_dirty.return_value = False

    state = json.load(open(temp_configfile))
    state["FORK_NAME"] = "peterbe"
    with open(temp_configfile, "w") as f:
        json.dump(state, f)

    runner = CliRunner()

# Path: gg/main.py
# class Config:
#     def __init__(self):
#         self.verbose = False  # default
#         self.configfile = DEFAULT_CONFIGFILE
#         try:
#             self.repo = get_repo()
#         except git.InvalidGitRepositoryError as exception:
#             error_out(f"{exception.args[0]} is not a git repository")
# 
# Path: gg/builtins/getback/gg_getback.py
# @cli.command()
# @click.option("-f", "--force", is_flag=True, default=False)
# @pass_config
# def getback(config, force=False):
#     """Goes back to the default branch, deletes the current branch locally
#     and remotely."""
#     repo = config.repo
# 
#     state = read(config.configfile)
#     origin_name = state.get("ORIGIN_NAME", "origin")
#     default_branch = get_default_branch(repo, origin_name)
#     active_branch = repo.active_branch
#     if active_branch.name == default_branch:
#         error_out(f"You're already on the {default_branch} branch.")
# 
#     if repo.is_dirty():
#         error_out(
#             'Repo is "dirty". ({})'.format(
#                 ", ".join([repr(x.b_path) for x in repo.index.diff(None)])
#             )
#         )
# 
#     branch_name = active_branch.name
# 
#     upstream_remote = None
#     fork_remote = None
#     for remote in repo.remotes:
#         if remote.name == origin_name:
#             # remote.pull()
#             upstream_remote = remote
#             break
#     if not upstream_remote:
#         error_out("No remote called {!r} found".format(origin_name))
# 
#     # Check out default branch
#     repo.heads[default_branch].checkout()
#     upstream_remote.pull(repo.heads[default_branch])
# 
#     # Is this one of the merged branches?!
#     # XXX I don't know how to do this "natively" with GitPython.
#     merged_branches = [
#         x.strip()
#         for x in repo.git.branch("--merged").splitlines()
#         if x.strip() and not x.strip().startswith("*")
#     ]
#     was_merged = branch_name in merged_branches
#     certain = was_merged or force
#     if not certain:
#         # Need to ask the user.
#         # XXX This is where we could get smart and compare this branch
#         # with the default branch.
#         certain = (
#             input("Are you certain {} is actually merged? [Y/n] ".format(branch_name))
#             .lower()
#             .strip()
#             != "n"
#         )
#     if not certain:
#         return 1
# 
#     if was_merged:
#         repo.git.branch("-d", branch_name)
#     else:
#         repo.git.branch("-D", branch_name)
# 
#     fork_remote = None
#     for remote in repo.remotes:
#         if remote.name == state.get("FORK_NAME"):
#             fork_remote = remote
#             break
#     if fork_remote:
#         fork_remote.push(":" + branch_name)
#         info_out("Remote branch on fork deleted too.")


# Path: gg/builtins/getback/tests/test_gg_getback.py
import json
import os
import tempfile
import shutil
import pytest
import requests_mock
from click.testing import CliRunner
from gg.main import Config
from gg.builtins.getback.gg_getback import getback

    with requests_mock.mock() as m:
        yield m


@pytest.yield_fixture
def temp_configfile():
    tmp_dir = tempfile.mkdtemp("gg-start")
    fp = os.path.join(tmp_dir, "state.json")
    with open(fp, "w") as f:
        json.dump({}, f)
    yield fp
    shutil.rmtree(tmp_dir)


def test_getback(temp_configfile, mocker):
    mocked_git = mocker.patch("git.Repo")
    mocked_git().working_dir = "gg-start-test"
    active_branch = mocker.MagicMock()
    mocked_git().active_branch = active_branch
    mocked_remote = mocker.MagicMock()
    mocked_remote.name = "origin"
    mocked_git().remotes.__iter__.return_value = [mocked_remote]
    mocked_git().is_dirty.return_value = False

    state = json.load(open(temp_configfile))
    state["FORK_NAME"] = "peterbe"
    with open(temp_configfile, "w") as f:
        json.dump(state, f)

    runner = CliRunner()

    config = Config()