#!/usr/bin/env python3

"""
Tool to help automate changes needed in commits during and after releases
"""

from __future__ import annotations

import argparse
import logging
import re
import sys
from datetime import datetime
from pathlib import Path
from subprocess import run

LOG = logging.getLogger(__name__)
NEW_VERSION_CHANGELOG_TEMPLATE = """\
## Unreleased

<!-- PR authors:
     Please include the PR number in the changelog entry, not the issue number -->

### Highlights

<!-- Include any especially major or disruptive changes here -->

### Stable style

<!-- Changes that affect Black's stable style -->

### Preview style

<!-- Changes that affect Black's preview style -->

### Configuration

<!-- Changes to how Black can be configured -->

### Packaging

<!-- Changes to how Black is packaged, such as dependency requirements -->

### Parser

<!-- Changes to the parser or to version autodetection -->

### Performance

<!-- Changes that improve Black's performance. -->

### Output

<!-- Changes to Black's terminal output and error messages -->

### _Blackd_

<!-- Changes to blackd -->

### Integrations

<!-- For example, Docker, GitHub Actions, pre-commit, editors -->

### Documentation

<!-- Major changes to documentation and policies. Small docs changes
     don't need a changelog entry. -->
"""


class NoGitTagsError(Exception): ...


# TODO: Do better with alpha + beta releases
# Maybe we vendor packaging library
def get_git_tags(versions_only: bool = True) -> list[str]:
    """Pull out all tags or calvers only"""
    cp = run(["git", "tag"], capture_output=True, check=True, encoding="utf8")
    if not cp.stdout:
        LOG.error(f"Returned no git tags stdout: {cp.stderr}")
        raise NoGitTagsError
    git_tags = cp.stdout.splitlines()
    if versions_only:
        return [t for t in git_tags if t[0].isdigit()]
    return git_tags


# TODO: Support sorting alpha/beta releases correctly
def tuple_calver(calver: str) -> tuple[int, ...]:  # mypy can't notice maxsplit below
    """Convert a calver string into a tuple of ints for sorting"""
    try:
        return tuple(map(int, calver.split(".", maxsplit=2)))
    except ValueError:
        return (0, 0, 0)


class SourceFiles:
    def __init__(self, black_repo_dir: Path):
        # File path fun all pathlib to be platform agnostic
        self.black_repo_path = black_repo_dir
        self.changes_path = self.black_repo_path / "CHANGES.md"
        self.docs_path = self.black_repo_path / "docs"
        self.version_doc_paths = (
            self.docs_path / "integrations" / "source_version_control.md",
            self.docs_path / "usage_and_configuration" / "the_basics.md",
            self.docs_path / "guides" / "using_black_with_jupyter_notebooks.md",
        )
        self.current_version = self.get_current_version()
        self.next_version = self.get_next_version()

    def __str__(self) -> str:
        return f"""\
> SourceFiles ENV:
  Repo path: {self.black_repo_path}
  CHANGES.md path: {self.changes_path}
  docs path: {self.docs_path}
  Current version: {self.current_version}
  Next version: {self.next_version}
"""

    def add_template_to_changes(self) -> int:
        """Add the template to CHANGES.md if it does not exist"""
        LOG.info(f"Adding template to {self.changes_path}")

        with self.changes_path.open("r", encoding="utf-8") as cfp:
            changes_string = cfp.read()

        if "## Unreleased" in changes_string:
            LOG.error(f"{self.changes_path} already has unreleased template")
            return 1

        templated_changes_string = changes_string.replace(
            "# Change Log\n",
            f"# Change Log\n\n{NEW_VERSION_CHANGELOG_TEMPLATE}",
        )

        with self.changes_path.open("w", encoding="utf-8") as cfp:
            cfp.write(templated_changes_string)

        LOG.info(f"Added template to {self.changes_path}")
        return 0

    def cleanup_changes_template_for_release(self) -> None:
        LOG.info(f"Cleaning up {self.changes_path}")

        with self.changes_path.open("r", encoding="utf-8") as cfp:
            changes_string = cfp.read()

        # Change Unreleased to next version
        changes_string = changes_string.replace(
            "## Unreleased", f"## Version {self.next_version}"
        )

        # Remove all comments
        changes_string = re.sub(r"(?m)^<!--(?>(?:.|\n)*?-->)\n+", "", changes_string)

        # Remove empty subheadings
        changes_string = re.sub(r"(?m)^###.+\n+(?=#)", "", changes_string)

        with self.changes_path.open("w", encoding="utf-8") as cfp:
            cfp.write(changes_string)

        LOG.debug(f"Finished Cleaning up {self.changes_path}")

    def get_current_version(self) -> str:
        """Get the latest git (version) tag as latest version"""
        return sorted(get_git_tags(), key=lambda k: tuple_calver(k))[-1]

    def get_next_version(self) -> str:
        """Workout the year and month + version number we need to move to"""
        base_calver = datetime.today().strftime("%y.%m")
        calver_parts = base_calver.split(".")
        base_calver = f"{calver_parts[0]}.{int(calver_parts[1])}"  # Remove leading 0
        git_tags = get_git_tags()
        same_month_releases = [
            t for t in git_tags if t.startswith(base_calver) and "a" not in t
        ]
        if len(same_month_releases) < 1:
            return f"{base_calver}.0"
        same_month_version = same_month_releases[-1].split(".", 2)[-1]
        return f"{base_calver}.{int(same_month_version) + 1}"

    def update_repo_for_release(self) -> int:
        """Update CHANGES.md + doc files ready for release"""
        self.cleanup_changes_template_for_release()
        self.update_version_in_docs()
        return 0  # return 0 if no exceptions hit

    def update_version_in_docs(self) -> None:
        for doc_path in self.version_doc_paths:
            LOG.info(f"Updating black version to {self.next_version} in {doc_path}")

            with doc_path.open("r", encoding="utf-8") as dfp:
                doc_string = dfp.read()

            next_version_doc = doc_string.replace(
                self.current_version, self.next_version
            )

            with doc_path.open("w", encoding="utf-8") as dfp:
                dfp.write(next_version_doc)

            LOG.debug(
                f"Finished updating black version to {self.next_version} in {doc_path}"
            )


def _handle_debug(debug: bool) -> None:
    """Turn on debugging if asked otherwise INFO default"""
    log_level = logging.DEBUG if debug else logging.INFO
    logging.basicConfig(
        format="[%(asctime)s] %(levelname)s: %(message)s (%(filename)s:%(lineno)d)",
        level=log_level,
    )


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "-a",
        "--add-changes-template",
        action="store_true",
        help="Add the Unreleased template to CHANGES.md",
    )
    parser.add_argument(
        "-d", "--debug", action="store_true", help="Verbose debug output"
    )
    args = parser.parse_args()
    _handle_debug(args.debug)
    return args


def main() -> int:
    args = parse_args()

    # Need parent.parent cause script is in scripts/ directory
    sf = SourceFiles(Path(__file__).parent.parent)

    if args.add_changes_template:
        return sf.add_template_to_changes()

    LOG.info(f"Current version detected to be {sf.current_version}")
    LOG.info(f"Next version will be {sf.next_version}")
    return sf.update_repo_for_release()


if __name__ == "__main__":  # pragma: no cover
    sys.exit(main())
