# -*- coding: utf-8 -*-

import re
import datetime
import os.path
import contextlib
import sys
import textwrap
from subprocess import Popen, PIPE

from kids.sh import ShellError, wrap
from kids.file import normpath, File
from kids.cache import cache


try:
    basestring  # attempt to evaluate basestring

    def isstr(s):
        return isinstance(s, basestring)
except NameError:

    def isstr(s):
        return isinstance(s, str)


@contextlib.contextmanager
def set_cwd(directory):
    curdir = os.getcwd()
    os.chdir(directory)
    try:
        yield
    finally:
        os.chdir(curdir)


WIN32 = sys.platform == 'win32'
if WIN32:
    PLT_CFG = {
        'close_fds': False,
    }
else:
    PLT_CFG = {
        'close_fds': True,
    }


class Proc(Popen):

    def __init__(self, command, env=None):
        super(Proc, self).__init__(
            command, stdin=PIPE, stdout=PIPE, stderr=PIPE,
            close_fds=PLT_CFG['close_fds'], env=env,
            universal_newlines=False)

        self.stdin = File(self.stdin)
        self.stdout = File(self.stdout)
        self.stderr = File(self.stderr)


class SubGitObjectMixin(object):

    def __init__(self, repos=None):
        if isstr(repos) or repos is None:
            repos = GitRepos(repos)
        self._repos = repos

    @property
    def git(self):
        """Simple delegation to ``repos`` original method."""
        return self._repos.git


GIT_FORMAT_KEYS = {
    'sha1': "%H",
    'sha1_short': "%h",
    'subject': "%s",
    'author_name': "%an",
    'author_email': "%ae",
    'author_date': "%ad",
    'author_date_timestamp': "%at",
    'committer_name': "%cn",
    'committer_date_timestamp': "%ct",
    'raw_body': "%B",
    'body': "%b",
    'parent_list_string': "%P",
    'decorate_string': "%D",
}

GIT_FULL_FORMAT_STRING = "%x00".join(GIT_FORMAT_KEYS.values())

REGEX_RFC822_KEY_VALUE = \
    r'(^|\n)(?P<key>[A-Z]\w+(-\w+)*): (?P<value>[^\n]*(\n\s+[^\n]*)*)'
REGEX_RFC822_POSTFIX = \
    r'(%s)+$' % REGEX_RFC822_KEY_VALUE


class GitCommit(SubGitObjectMixin):
    r"""Represent a Git Commit and expose through its attribute many information

    Let's create a fake GitRepos:

        >>> from minimock import Mock
        >>> repos = Mock("gitRepos")

    Initialization:

        >>> repos.git = Mock("gitRepos.git")