#! /usr/bin/env python3

import logging
import requests
from git import Repo

# NEED to modify populate PR/create new function to enable editing existing PR
"""Repository interface and Repository-specific functions"""

logger = logging.getLogger(__name__)


def compile_branch(repo: Repo, branch_name: str = "") -> tuple:
    """Compile a specific branch and return its commit tree"""
    if branch_name:
        logger.info(f"Checking out branch: {branch_name}")
        repo.git.checkout(branch_name)
    else:
        branch_name = repo.active_branch.name
        logger.info(f"On branch: {branch_name}")
    commit = repo.head.commit.tree
    return commit, branch_name


def check_merge_status(repo: Repo, derived_name: str, source_name: str) -> bool:
    """Check if source branch is merged into derived branch"""
    commits_ahead = repo.iter_commits(f"{derived_name}..{source_name}")
    ahead_count = sum(1 for _ in commits_ahead)
    if ahead_count > 0:
        return False
    return True


def identify_changed_files(
    src_commit: object, der_commit: object, suffix: str
) -> tuple[list[str], list[str], list[str]]:
    """Identify changed files between two commits"""
    # get the diff
    diff = src_commit.diff(der_commit)
    added_files = [
        x.b_path for x in diff.iter_change_type("A") if x.b_path.endswith(suffix)
    ]
    modified_files = [
        x.b_path for x in diff.iter_change_type("M") if x.b_path.endswith(suffix)
    ]
    removed_files = [
        x.b_path for x in diff.iter_change_type("D") if x.b_path.endswith(suffix)
    ]

    logger.debug(f"Added files: {added_files}")
    logger.debug(f"Modified files: {modified_files}")
    logger.debug(f"Removed files: {removed_files}")
    return added_files, modified_files, removed_files


def parse_branches(repo, derived_branch, source_branch, suffix):
    """Parse source and derived branches to identify changed files"""
    src_commit, source_branch = compile_branch(repo, branch_name=source_branch)
    der_commit, derived_branch = compile_branch(repo, branch_name=derived_branch)

    if source_branch == derived_branch:
        logger.warning(
            f"Source branch {source_branch} is the same as derived branch {derived_branch}"
        )

    added_files, modified_files, removed_files = identify_changed_files(
        src_commit, der_commit, suffix
    )
    if not (added_files or modified_files or removed_files):
        logger.warning(
            "No added, modified, or removed WDL files detected between source and derived branches"
        )

    return derived_branch, source_branch, added_files, modified_files, removed_files


def download_pr(owner, repo, pr_number):
    """Download a PR from GitHub and return its body text."""

    url = f"https://api.github.com/repos/{owner}/{repo}/pulls/{pr_number}"
    response = requests.get(url)
    if response.status_code == 200:
        pr_data = response.json()
        return pr_data.get("body", "")
    else:
        raise Exception(f"Failed to fetch PR: {response.status_code} - {response.text}")
