"""Utility to update the version number in all locations.

Example usage
-------------

To update the version numbers in all files to "1.0.0", run either of the
following:
```bash
python3 update_version.py -v 1.0.0
python3 update_version.py --version 1.0.0
```

To update the C++ version numbers to "1.0.0.3" and the Python version
numbers to "1.0.0dev3", run either of the following:
```bash
python3 update_version.py -v 1.0.0.dev3
python3 update_version.py --version 1.0.0.dev3
```
"""

import argparse
import os
import re


def replace_version(content, version):
    """Replace all occurences of version in content."""
    content = re.sub(
        r"((?:VERSION)|(?:version))([\s=]+)([\"']).+?\3",
        lambda matches: f"{matches[1]}{matches[2]}{matches[3]}{version}{matches[3]}",
        content,
    )
    return content


parser = argparse.ArgumentParser(description="Update version numbering")
parser.add_argument(
    "-v",
    "--version",
    metavar="version",
    help="Version number to update to",
    required=True,
)

args = parser.parse_args()

version = args.version
pyversion = version
if ".dev" in version:
    version = version.replace("dev", "")

print("About to update version numbers to:")
print(f"    C++ version: {version}")
print(f"    Python version: {pyversion}")

answer = None
while answer not in ["y", "n"]:
    if answer is None:
        answer = input("Do you want to proceed? [y/n] ").lower()
    else:
        answer = input("Please enter y or n: ").lower()

if answer == "n":
    print("Aborting.")
    exit()


path = os.path.dirname(os.path.realpath(__file__))

for file in ["CMakeLists.txt", "cpp/CMakeLists.txt", "python/CMakeLists.txt"]:
    print(f"Replacing C++-style version numbers in {file}.")
    with open(os.path.join(path, file)) as f:
        content = f.read()
    with open(os.path.join(path, file), "w") as f:
        f.write(replace_version(content, version))

for file in ["pyproject.toml", "python/pyproject.toml"]:
    print(f"Replacing Python-style version numbers in {file}.")
    with open(os.path.join(path, file)) as f:
        content = f.read()
    with open(os.path.join(path, file), "w") as f:
        f.write(replace_version(content, pyversion))
