import datetime
import logging
from collections.abc import Iterator
from pathlib import Path

import git

from personal_data.activity import HIDDEN_LABEL_CATEGORY, ActivitySample, Label

logger = logging.getLogger(__name__)


def determine_default_branch(repo: git.Repo):
    try:
        repo.commit('main')
        return 'main'
    except:
        return 'master'


def determine_project_name(repo: git.Repo) -> str:
    remotes = repo.remotes
    if len(remotes) > 0:
        return remotes.origin.url.removeprefix('git@gitfub.space:')
    return Path(repo.working_tree_dir).name


def get_samples_from_project(repo: git.Repo) -> Iterator[ActivitySample]:
    project_name = determine_project_name(repo)
    assert project_name is not None

    # TODO: Branch on main or master or default

    repo.commit()

    for commit in repo.iter_commits(determine_default_branch(repo)):
        labels = [Label(HIDDEN_LABEL_CATEGORY, 'total')]
        labels.append(Label('project', project_name))
        labels.append(Label('author', commit.author.email))

        authored_date = datetime.datetime.fromtimestamp(
            commit.authored_date,
            tz=datetime.UTC,
        )
        committed_date = datetime.datetime.fromtimestamp(
            commit.committed_date,
            tz=datetime.UTC,
        )

        yield ActivitySample(
            labels=tuple(labels),
            start_at=None,
            end_at=authored_date,
        )
        if authored_date != committed_date:
            yield ActivitySample(
                labels=tuple(labels),
                start_at=None,
                end_at=committed_date,
            )
        del labels


def iterate_samples_from_git_repository(repo_path: Path) -> Iterator[ActivitySample]:
    try:
        yield from get_samples_from_project(git.Repo(repo_path))
    except git.exc.InvalidGitRepositoryError:
        logger.warning('Ignoring non-repo %s', repo_path)