#!/usr/bin/python3

"""
Rename Python SO file with ABI tags to original filename
"""


import os
import re
import sys
import logging
import argparse


#: Stolen from /usr/share/dh-python/dhpython/interpreter.py
EXTFILE_RE = re.compile(
    r"""
    (?P<name>.*?)
    (?:\.
        (?P<stableabi>abi\d+)
     |(?:\.
        (?P<soabi>
            (?P<impl>cpython|pypy)
            -
            (?P<ver>\d{2})
            (?P<flags>[a-z]*)
        )?
        (?:
            (?:(?<!\.)-)?  # minus sign only if soabi is defined
            (?P<multiarch>[^/]*?)
        )?
    ))?
    (?P<debug>_d)?
    \.so$""",
    re.VERBOSE,
)


def cli_args() -> argparse.Namespace:
    """
    Command line arguments
    """

    parser = argparse.ArgumentParser(description=__doc__.strip(), formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument(
        "-f", "--files", type=str, nargs="+", help="Files to rename", metavar="/path/to/filename.cpython-37m-x86_64-linux-gnu.so", required=True
    )
    return parser.parse_args()


def rename_if_possible(*filepath: str) -> None:
    """
    Rename filename if possible
    """

    for filename in filepath:

        abspath = os.path.abspath(filename)

        if not os.path.exists(abspath):
            logging.warning("Ignoring non-existent file %s", abspath)
            continue

        if not os.path.isfile(abspath):
            logging.warning("Ignoring file %s which is not a regular file", abspath)
            continue

        filename = os.path.basename(abspath)
        filedir = os.path.dirname(abspath)
        parsed = EXTFILE_RE.match(filename)

        if not parsed:
            logging.warning("Ignoring file %s which does not match proper pattern", abspath)
            continue

        info = parsed.groupdict()
        new_filename = info["name"] + ".so"

        if new_filename == filename:
            logging.warning("Ignoring file %s which is already named correctly", abspath)
            continue

        new_abspath = os.path.join(filedir, new_filename)
        os.rename(abspath, new_abspath)
        logging.info("File %s renamed to %s", abspath, new_abspath)


if __name__ == "__main__":

    logging.basicConfig(level=logging.INFO, format="%(levelname)-8s [PyAbiToSo] %(message)s")
    CONFIG = cli_args()
    rename_if_possible(*CONFIG.files)
