# Copyright 2017 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Git repo metrics."""

from __future__ import absolute_import

import logging
import os
import subprocess

from chromite.lib import metrics


logger = logging.getLogger(__name__)


class _GitRepo:
    """Helper class for running git commands."""

    def __init__(self, gitdir):
        self._gitdir = gitdir

    def _get_git_command(self):
        return ["git", "--git-dir", self._gitdir]

    def _check_output(self, args, **kwargs):
        return subprocess.check_output(
            self._get_git_command() + list(args), **kwargs
        ).decode("utf-8")

    def get_commit_hash(self):
        """Return commit hash string."""
        return self._check_output(["rev-parse", "HEAD"]).strip()

    def get_commit_time(self):
        """Return commit time as UNIX timestamp int."""
        return int(
            self._check_output(["show", "-s", "--format=%ct", "HEAD"]).strip()
        )

    def get_unstaged_changes(self):
        """Return number of unstaged changes as (added, deleted)."""
        added_total, deleted_total = 0, 0
        # output looks like:
        # '1\t2\tfoo\n3\t4\tbar\n'
        # '-\t-\tbinary_file\n'
        output = self._check_output(["diff-index", "--numstat", "HEAD"])
        stats_strings = (line.split() for line in output.splitlines())
        for added, deleted, _path in stats_strings:
            if added != "-":
                added_total += int(added)
            if deleted != "-":
                deleted_total += int(deleted)
        return added_total, deleted_total


class _GitMetricCollector:
    """Class for collecting metrics about a git repository.

    The constructor takes the arguments: `gitdir`, `metric_path`.
    `gitdir` is the path to the Git directory to collect metrics for and
    may start with a tilde (expanded to a user's home directory).
    `metric_path` is the Monarch metric path to report to.
    """

    _commit_hash_metric = metrics.StringMetric(
        "git/hash", description="Current Git commit hash."
    )

    _timestamp_metric = metrics.GaugeMetric(
        "git/timestamp",
        description="Current Git commit time as seconds since Unix Epoch.",
    )

    _unstaged_changes_metric = metrics.GaugeMetric(
        "git/unstaged_changes", description="Unstaged Git changes."
    )

    def __init__(self, gitdir, metric_path):
        self._gitdir = gitdir
        self._gitrepo = _GitRepo(os.path.expanduser(gitdir))
        self._fields = {"repo": gitdir}
        self._metric_path = metric_path

    def collect(self):
        """Collect metrics."""
        try:
            self._collect_commit_hash_metric()
            self._collect_timestamp_metric()
            self._collect_unstaged_changes_metric()
        except subprocess.CalledProcessError as e:
            logger.warning(
                "Error collecting git metrics for %s: %s", self._gitdir, e
            )

    def _collect_commit_hash_metric(self):
        commit_hash = self._gitrepo.get_commit_hash()
        logger.debug("Collecting Git hash %r for %r", commit_hash, self._gitdir)
        self._commit_hash_metric.set(commit_hash, self._fields)

    def _collect_timestamp_metric(self):
        commit_time = self._gitrepo.get_commit_time()
        logger.debug(
            "Collecting Git timestamp %r for %r", commit_time, self._gitdir
        )
        self._timestamp_metric.set(commit_time, self._fields)

    def _collect_unstaged_changes_metric(self):
        added, deleted = self._gitrepo.get_unstaged_changes()
        self._unstaged_changes_metric.set(
            added, fields=dict(change_type="added", **self._fields)
        )
        self._unstaged_changes_metric.set(
            deleted, fields=dict(change_type="deleted", **self._fields)
        )


_CHROMIUMOS_DIR = "~chromeos-test/chromiumos/"

_repo_collectors = (
    # TODO(ayatane): We cannot access chromeos-admin because we are
    # running as non-root.
    _GitMetricCollector(
        gitdir="/root/chromeos-admin/.git", metric_path="chromeos-admin"
    ),
    _GitMetricCollector(
        gitdir=_CHROMIUMOS_DIR + "chromite/.git", metric_path="chromite"
    ),
    _GitMetricCollector(
        gitdir="/usr/local/autotest/.git", metric_path="installed_autotest"
    ),
)


def collect_git_metrics():
    """Collect metrics for Git repository state."""
    for collector in _repo_collectors:
        collector.collect()
