#!/usr/bin/env python3
#
"""Bumps semantic version in pyproject.toml and module.__init__ and then
commits and tags the change.

This script is a monument to over-automation and misdirected laziness. Don't be
like me.
"""
import argparse
import os
import pathlib
import subprocess
from typing import Any, Dict, List, cast

import semver
import toml


def parse_args() -> argparse.Namespace:
    """Define an argument parser and return the parsed arguments."""
    parser = argparse.ArgumentParser(
        prog="bump",
        description="bumps a project revision",
    )
    parser.add_argument(
        "--major",
        help="Bump the major revision",
        action="store_true",
        default=False,
    )
    parser.add_argument(
        "--minor",
        help="Bump the minor revision",
        action="store_true",
        default=False,
    )
    parser.add_argument(
        "--patch",
        help="Bump the patch revision",
        action="store_true",
        default=False,
    )

    return parser.parse_args()


def subshell(cmd: List[str]) -> bool:
    """Take a command as a list of strings and run it in a subshell.  If the
    command succeeds, return True. Otherwise, return False."""
    proc = subprocess.run(cmd)
    if proc.returncode == 0:
        return True
    else:
        print(f"Command {cmd} returned non-zero exit status {proc.returncode}")
        return False


def bump_version(current_version: str) -> str:
    args = parse_args()

    if args.major:
        return str(semver.VersionInfo.parse(current_version).bump_major())
    elif args.minor:
        return str(semver.VersionInfo.parse(current_version).bump_minor())
    elif args.patch:
        return str(semver.VersionInfo.parse(current_version).bump_patch())
    else:
        return str(current_version)


def main() -> None:

    # bump pyproject.toml version
    root_dir = pathlib.Path(__file__).parent.parent
    with open(os.path.join(root_dir, "pyproject.toml"), mode="r+") as f:
        pyproject: Dict[str, Any] = cast(Dict[str, Any], toml.load(f))

        current_version = pyproject["tool"]["poetry"]["version"]
        new_version = bump_version(current_version)

        if new_version != current_version:
            pyproject["tool"]["poetry"]["version"] = str(new_version)
            f.seek(0)
            f.truncate()
            toml.dump(pyproject, f)

    # bump module __init__.py version
    with open(
        os.path.join(root_dir, "downforeveryone/__init__.py"), mode="r+"
    ) as f:
        lines = "".join(
            [
                line.replace(
                    f'__version__ = "{current_version}"',
                    f'__version__ = "{new_version}"',
                )
                for line in f
            ]
        )
        f.seek(0)
        f.truncate()
        f.write(lines)

    # commit the changes
    subshell(["git", "reset"]) and subshell(
        [
            "git",
            "commit",
            "pyproject.toml",
            "downforeveryone/__init__.py",
            "-m",
            f'"Bump version from {current_version} to {new_version}"',
        ]
    ) and subshell(
        [
            "git",
            "tag",
            f"v{new_version}",
        ]
    )


if __name__ == "__main__":
    main()

# EOF
