# coding: utf8
# Debian Contributors data source data mining tools
#
# Copyright (C) 2013--2014  Enrico Zini <enrico@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
from .. import scanner
from ..types import *
import datetime

__all__ = ["GitDirs", "GitLogs"]

class GitDirs(scanner.Scanner):
    """
    Scan git directories using file attributes to detect contributions.

    Generates `login` types of identifiers, using the usernames of the system
    where it is run.

    Example::

        contribution: committer
        method: gitdirs
        dirs: /srv/git.debian.org/git/collab-maint/*.git
        url: https://alioth.debian.org/users/{user}/
    """
    dirs = scanner.GlobField(blank=False, help_text="""
                             ``.git`` directories to scan. You can give one or more,
                             and even use shell-style globbing.
                             """)
    url = scanner.CharField(help_text="""
                            template used to build URLs to link to people's contributions.
                            ``{user}`` will be replaced with the username
                            """)

    def scan(self):
        from .utils.filesystem import Filesystem

        scan = Filesystem()
        for d in self.dirs:
            scan.scan_git_repo(d)
        if self.url:
            tpl = self.url
            for ident, begin, end in scan.contributions():
                yield ident, begin, end, tpl.format(user=ident.id)
        else:
            for ident, begin, end in scan.contributions():
                yield ident, begin, end, None


class GitLogs(scanner.Scanner):
    """
    Scan git logs, taking note of committer and author activity

    Generates `email` types of identifiers, trusting whatever is in the git
    log.

    Example::

        contribution: committer
        method: gitlogs
        dirs: /srv/git.debian.org/git/collab-maint/*.git
    """
    dirs = scanner.GlobField(blank=False, help_text="""
                             ``.git`` directories to scan. You can give one or more,
                             and even use shell-style globbing.
                             """)

    def scan(self):
        from .utils.proc import stream_command_stdout
        from .utils.mine import Aggregate

        contribs = Aggregate()
        for d in self.dirs:
            cmd = ["git", "--git-dir", d, "log", "--all", "--pretty=tformat:%ae %at %ce %ct"]
            for line in stream_command_stdout(cmd):
                ae, at, ce, ct = line.split()
                contribs.add(ae, int(at))
                contribs.add(ce, int(ct))

        for email, (begin, end) in contribs.iteritems():
            ident = Identifier("email", email)
            begin = datetime.date.fromtimestamp(begin)
            end = datetime.date.fromtimestamp(end)
            yield ident, begin, end, None
