#!/usr/bin/env python3

import os, re, stat, sys
from io import open


def list_whence():
    with open("WHENCE", encoding="utf-8") as whence:
        for line in whence:
            match = re.match(r'(?:RawFile|File|Source):\s*"(.*)"', line)
            if match:
                yield match.group(1)
                continue
            match = re.match(r"(?:RawFile|File|Source):\s*(\S*)", line)
            if match:
                yield match.group(1)
                continue
            match = re.match(
                r"Licen[cs]e: (?:.*\bSee (.*) for details\.?|(\S*))\n", line
            )
            if match:
                if match.group(1):
                    for name in re.split(r", | and ", match.group(1)):
                        yield name
                    continue
                if match.group(2):
                    # Just one word - may or may not be a filename
                    if not re.search(
                        r"unknown|distributable", match.group(2), re.IGNORECASE
                    ):
                        yield match.group(2)
                        continue


def list_whence_files():
    with open("WHENCE", encoding="utf-8") as whence:
        for line in whence:
            match = re.match(r"(?:RawFile|File):\s*(.*)", line)
            if match:
                yield match.group(1).replace(r"\ ", " ").replace('"', "")
                continue


def list_links_list():
    with open("WHENCE", encoding="utf-8") as whence:
        for line in whence:
            match = re.match(r"Link:\s*(.*)", line)
            if match:
                linkname, target = match.group(1).split("->")

                linkname = linkname.strip().replace(r"\ ", " ").replace('"', "")
                target = target.strip().replace(r"\ ", " ").replace('"', "")

                # Link target is relative to the link
                target = os.path.join(os.path.dirname(linkname), target)
                target = os.path.normpath(target)

                yield (linkname, target)
                continue


def list_git():
    git_files = os.popen("git ls-files")
    for line in git_files:
        yield line.rstrip("\n")

    if git_files.close():
        sys.stderr.write("W: git file listing failed, skipping some validation\n")


def main():
    ret = 0
    whence_list = list(list_whence())
    whence_files = list(list_whence_files())
    links_list = list(list_links_list())
    whence_links = list(zip(*links_list))[0]
    known_files = set(name for name in whence_list if not name.endswith("/")) | set(
        [
            ".codespell.cfg",
            ".editorconfig",
            ".gitignore",
            ".gitlab-ci.yml",
            ".pre-commit-config.yaml",
            "Dockerfile",
            "Makefile",
            "LICENSE",
            "README.md",
            "WHENCE",
            "build_packages.py",
            "check_whence.py",
            "contrib/process_linux_firmware.py",
            "contrib/templates/debian.changelog",
            "contrib/templates/debian.control",
            "contrib/templates/debian.copyright",
            "contrib/templates/rpm.spec",
            "copy-firmware.sh",
            "dedup-firmware.sh",
        ]
    )
    known_prefixes = set(name for name in whence_list if name.endswith("/"))
    git_files = set(list_git())
    executable_files = set(
        [
            "build_packages.py",
            "carl9170fw/genapi.sh",
            "carl9170fw/autogen.sh",
            "check_whence.py",
            "contrib/process_linux_firmware.py",
            "copy-firmware.sh",
            "dedup-firmware.sh",
        ]
    )

    for name in set(name for name in whence_files if name.endswith("/")):
        sys.stderr.write("E: %s listed in WHENCE as File, but is directory\n" % name)
        ret = 1

    for name in set(name for name in whence_files if whence_files.count(name) > 1):
        sys.stderr.write("E: %s listed in WHENCE twice\n" % name)
        ret = 1

    for name in set(link for link in whence_links if whence_links.count(link) > 1):
        sys.stderr.write("E: %s listed in WHENCE twice\n" % name)
        ret = 1

    for name in set(file for file in whence_files if os.path.islink(file)):
        sys.stderr.write("E: %s listed in WHENCE as File, but is a symlink\n" % name)
        ret = 1

    for name in set(link[0] for link in links_list if os.path.islink(link[0])):
        sys.stderr.write("E: %s listed in WHENCE as Link, is in tree\n" % name)
        ret = 1

    invalid_targets = set(link[0] for link in links_list)
    for link, target in sorted(links_list):
        if target in invalid_targets:
            sys.stderr.write(
                "E: target %s of link %s is also a link\n" % (target, link)
            )
            ret = 1

    for name in sorted(list(known_files - git_files) if len(git_files) else list()):
        sys.stderr.write("E: %s listed in WHENCE does not exist\n" % name)
        ret = 1

    # A link can point to a file...
    valid_targets = set(git_files)

    # ... or to a directory
    for target in set(valid_targets):
        dirname = target
        while True:
            dirname = os.path.dirname(dirname)
            if dirname == "":
                break
            valid_targets.add(dirname)

    for link, target in sorted(links_list if len(git_files) else list()):
        if target not in valid_targets:
            sys.stderr.write(
                "E: target %s of link %s in WHENCE does not exist\n" % (target, link)
            )
            ret = 1

    for name in sorted(list(git_files - known_files)):
        # Ignore subdirectory changelogs and GPG detached signatures
        if name.endswith("/ChangeLog") or (
            name.endswith(".asc") and name[:-4] in known_files
        ):
            continue

        # Ignore unknown files in known directories
        for prefix in known_prefixes:
            if name.startswith(prefix):
                break
        else:
            sys.stderr.write("E: %s not listed in WHENCE\n" % name)
            ret = 1

    for name in sorted(list(executable_files)):
        mode = os.stat(name).st_mode
        if not (mode & stat.S_IXUSR and mode & stat.S_IXGRP and mode & stat.S_IXOTH):
            sys.stderr.write("E: %s is missing execute bit\n" % name)
            ret = 1

    for name in sorted(list(git_files - executable_files)):
        mode = os.stat(name).st_mode
        if stat.S_ISDIR(mode):
            if not (
                mode & stat.S_IXUSR and mode & stat.S_IXGRP and mode & stat.S_IXOTH
            ):
                sys.stderr.write("E: %s is missing execute bit\n" % name)
                ret = 1
        elif stat.S_ISREG(mode):
            if mode & stat.S_IXUSR or mode & stat.S_IXGRP or mode & stat.S_IXOTH:
                sys.stderr.write("E: %s incorrectly has execute bit\n" % name)
                ret = 1
        else:
            sys.stderr.write("E: %s is neither a directory nor regular file\n" % name)
            ret = 1

    return ret


if __name__ == "__main__":
    sys.exit(main())
