#!/usr/bin/env python3

"""
helper script to extract file permissions from the rpm .spec file
for synchronizing into the debian packages.

we assume the .spec file is kept up date for fedora since sssd is from red hat.
to update the debian .postinst scripts to apply the intended upstream permissions,
you can use this tool to convert %(attr) and %(caps) entries to 'regular'
chown, chmod and setcap invocations.

to be able to assign the entries from spec's %files sections to debian binary packages,
use the <section> parameter to extract the same-named section as the debian binary package.
"""

import argparse
import re
import shlex


def main():
    cli = argparse.ArgumentParser(description="RPM spec converter for sssd packaging.")
    cli.add_argument("-f", "--file", default="contrib/sssd.spec.in",
                     help="Path to the input spec file, default=%(default)s")
    cli.add_argument("section", help=(
        "deb binary package name to select the .spec file's '%%files <name>' section "
        " (example: 'common' or 'sssd-common')"
    ))
    args = cli.parse_args()

    section_name = args.section.lstrip("sssd-")

    start_pattern = re.compile(rf"^%files\s+{re.escape(section_name)}(\s|$)")

    end_pattern = re.compile(r"^%files(\s|$)")
    attr_pattern = re.compile(r"%attr\((?P<perms>\w+),(?P<user>\w+),(?P<group>\w+)\)")
    caps_pattern = re.compile(r"%caps\((?P<caps>[^)]+)\)")

    extracting = False

    with open(args.file, 'r') as fd:
        for line in fd:
            line = line.strip()
            if not line:
                continue

            if start_pattern.match(line):
                extracting = True
                continue

            if not extracting:
                continue

            if end_pattern.match(line):
                extracting = False
                break

            parts = shlex.split(line)
            if not any(parts[0].startswith(prefix) for prefix in ("%attr", "%caps")):
                continue

            path = parts[-1]
            path = path.replace('%{', '${')

            # %attr -> permissions
            if attr_match := attr_pattern.search(line):
                attrs = attr_match.groupdict()
                print(f'chown {attrs["user"]}:{attrs["group"]} "{path}"')
                print(f'chmod {attrs["perms"]} "{path}"')

            # %caps -> capabilities
            if caps_match := caps_pattern.search(line):
                print(f'setcap "{caps_match.groupdict()["caps"]}" "{path}"')


if __name__ == "__main__":
    main()
