"""
pygithub based help functions for interacting with the github api.
"""

from github import Github
from public import public
import codekit.codetools as codetools
import github
import itertools
import logging
import textwrap

logging.basicConfig()
logger = logging.getLogger('codekit')


class CaughtGitError(Exception):
    """Simple exception class intended to bundle together a github.Repository
    object and a thrown exception
    """
    def __init__(self, repo, caught):
        assert isinstance(repo, github.Repository.Repository), type(repo)
        assert isinstance(caught, Exception)

        self.repo = repo
        self.caught = caught

    def __str__(self):
        return textwrap.dedent("""\
            Caught: {name}
              In repo: {repo}
              Message: {e}\
            """.format(
            name=type(self.caught),
            repo=self.repo.full_name,
            e=str(self.caught)
        ))


class CaughtTeamError(Exception):
    """Simple exception class intended to bundle together a github.Repository
    object and a thrown exception
    """
    def __init__(self, team, caught):
        assert isinstance(team, github.Team.Team), type(team)
        assert isinstance(caught, Exception)

        self.team = team
        self.caught = caught

    def __str__(self):
        return textwrap.dedent("""\
            Caught: {name}
              In team: {team}@{org}
              Message: {e}\
            """.format(
            name=type(self.caught),
            team=self.team.slug,
            org=self.team.organization.login,
            e=str(self.caught)
        ))


@public
def login_github(token_path=None, token=None):
    """Log into GitHub using an existing token.

    Parameters
    ----------
    token_path : str, optional
        Path to the token file. The default token is used otherwise.

    token: str, optional
        Literial token string. If specifified, this value is used instead of
        reading from the token_path file.

    Returns
    -------
    gh : :class:`github.GitHub` instance
        A GitHub login instance.
    """

    token = codetools.github_token(token_path=token_path, token=token)
    return Github(token)


@public
def find_tag_by_name(repo, tag_name, safe=True):
    """Find tag by name in a github Repository

    Parameters
    ----------
    repo: :class:`github.Repository` instance

    tag_name: str
        Short name of tag (not a fully qualified ref).

    safe: bool, optional
        Defaults to `True`. When `True`, `None` is returned on failure. When
        `False`, an exception will be raised upon failure.

    Returns
    -------
    gh : :class:`github.GitRef` instance or `None`

    Raises
    ------
    github.UnknownObjectException
        If git tag name does not exist in repo.
    """
    tagfmt = 'tags/{ref}'.format(ref=tag_name)

    try:
        ref = repo.get_git_ref(tagfmt)
        if ref and ref.ref:
            return ref
    except github.UnknownObjectException:
        if not safe:
            raise

    return None


@public
def get_repos_by_team(teams):
    """Find repos by membership in github team(s).

    Parameters
    ----------
    teams: list(github.Team.Team)
        list of Team objects

    Returns
    -------
    generator of github.Repository.Repository objects

    Raises
    ------
    github.GithubException
        Upon error from github api
    """
    return itertools.chain.from_iterable(
        t.get_repos() for t in teams
    )

@@ -368,32 +368,36 @@
 undle together a
+%0A   
  github.Reposito
@@ -390,36 +390,43 @@
 ithub.Repository
-%0A   
+.Repository
  object and a th
@@ -1048,26 +1048,25 @@
  github.
-Repository
+Team.Team
 %0A    obj
@@ -1544,16 +1544,16 @@
 m.slug,%0A
-
         
@@ -1630,24 +1630,691 @@
        ))%0A%0A%0A
+class CaughtOrganizationError(Exception):%0A    %22%22%22Simple exception class intended to bundle together a%0A    github.Organization.Organization object and a thrown exception%0A    %22%22%22%0A    def __init__(self, org, caught):%0A        assert isinstance(org, github.Organization.Organization), type(org)%0A        assert isinstance(caught, Exception)%0A%0A        self.org = org%0A        self.caught = caught%0A%0A    def __str__(self):%0A        return textwrap.dedent(%22%22%22%5C%0A            Caught: %7Bname%7D%0A              In org: %7Borg%7D%0A              Message: %7Be%7D%5C%0A            %22%22%22.format(%0A            name=type(self.caught),%0A            org=self.org.login,%0A            e=str(self.caught)%0A        ))%0A%0A%0A
 @public%0Adef 

add pygithub.CaughtOrganizationError exception class