from subprocess import PIPE
from subprocess import Popen
from subprocess import STDOUT
from subprocess import SubprocessError

import re

from linaropy.git.worktree import Worktree


class CommandPrinter(object):
    """Command consumer that just prints the commands that it receives."""

    def consume(self, command, directory):
        print("{}$ {}".format(directory, ' '.join(command)))


class CommandRunner(object):
    """Command consumer that runs the commands that it receives."""

    def consume(self, command, directory):
        """
        Run the given command in the given directory and print the stdout and
        stderr. If 'directory' is None, the current working directory is used.
        If an exception is thrown while running the command, it will be rethrown
        as a RuntimeError.
        """
        try:
            with Popen(command, stdout=PIPE, stderr=STDOUT, cwd=directory) as process:
                for line in process.stdout:
                    print(str(line, 'utf-8'), end='')
            if process.returncode != 0:
                raise RuntimeError(
                    "Command failed with return code: {}\n".format(
                        process.returncode))
        except SubprocessError as exc:
            raise RuntimeError(
                "Error while running command\n{}".format(str(exc.output, 'utf-8'))) from exc


# FIXME: repo.pushToBranch doesn't work, because it doesn't handle remote
# branches properly. Furthermore, there's no support for getting the remote URL,
# so we need to resort to raw git commands. We may also consider moving the
# functionality for parsing info out of the remote URL into the repo object.
from sh import git
from linaropy.cd import cd


def get_user_from_remote(url):
    """Get the username used as part of the remote URL, or None.

    The remote URLs that we expect to see look like $protocol://$user@$location.
    If they look any different, we won't be able to parse them.
    """
    pattern = re.compile("(.*://)?(?P<user>.*)@(.*)\n?")
    match = pattern.match(str(url))
    if match is None:
        return None
    return match.group('user')


def get_remote_branch(repo, local_branch):
    """
    Get the name of the remote branch corresponding to the given local branch.
    """
    with cd(repo.repodir):
        remote = git("remote", "get-url", "--push", "origin").strip()
    user = get_user_from_remote(remote)
    if not user:
        raise EnvironmentError("Couldn't parse user from {}.".format(remote))

    remote_branch = "linaro-local/{}/{}".format(user, local_branch)
    if not repo.is_valid_branch_name(remote_branch):
        raise EnvironmentError(
            "{} is not a valid branch name.".format(remote_branch))

    return remote_branch


def push_branch(proj, local_branch, remote_branch, pathToRepo):
    """Push the given local branch into origin's given remote branch."""
    repo = Worktree(proj, pathToRepo)
    with cd(repo.repodir):
        git("push", "-u", "origin", "+{}:{}".format(local_branch, remote_branch))
