#!/usr/bin/env python
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Subversion pre-commit hook script that runs user configured commands
to validate files in the commit and reject the commit if the commands
exit with a non-zero exit code.  The script expects a validate-files.conf
file placed in the conf dir under the repo the commit is for.

Note: As changed file paths $FILE are always represented as a Unicode (Py3)
      or UTF-8 (Py2) strings, you might need to set apropriate locale and
      PYTHONIOENCODING environment variable for this script and
      commands to handle non-ascii path and command outputs, especially
      you want to use svnlook cat command to inspect file contents."""

import sys
import os
import subprocess
import fnmatch

# Deal with the rename of ConfigParser to configparser in Python3
try:
    # Python >= 3.0
    import configparser
    ConfigParser = configparser.ConfigParser
except ImportError:
    # Python < 3.0
    import ConfigParser as configparser
    ConfigParser = configparser.SafeConfigParser

class Config(ConfigParser):
    """Superclass of SafeConfigParser with some customizations
    for this script"""
    def optionxform(self, option):
        """Redefine optionxform so option names are case sensitive"""
        return option

    def getlist(self, section, option):
        """Returns value of option as a list using whitespace to
        split entries"""
        value = self.get(section, option)
        if value:
            return value.split()
        else:
            return None

    def get_matching_rules(self, repo):
        """Return list of unique rules names that apply to a given repo"""
        rules = {}
        for option in self.options('repositories'):
            if fnmatch.fnmatch(repo, option):
                for rule in self.getlist('repositories', option):
                    rules[rule] = True
        return rules.keys()

    def get_rule_section_name(self, rule):
        """Given a rule name provide the section name it is defined in."""
        return 'rule:%s' % (rule)

class Commands:
    """Class to handle logic of running commands"""
    def __init__(self, config):
        self.config = config

    def svnlook_changed(self, repo, txn):
        """Provide list of files changed in txn of repo"""
        svnlook = self.config.get('DEFAULT', 'svnlook')
        cmd = "'%s' changed -t '%s' '%s'" % (svnlook, txn, repo)
        p = subprocess.Popen(cmd, shell=True,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        changed = []
        while True:
            line = p.stdout.readline()
            if not line:
                break
            line = line.strip()
            text_mod = line[0:1]
            # Only if the contents of the file changed (by addition or update)
            # directories always end in / in the svnlook changed output
            if line[-1:] != b"/" and (text_mod == b"A" or text_mod == b"U"):
                changed_path = line[4:]
                if not isinstance(changed_path, str):
                    # svnlook always uses UTF-8 for internal path
                    changed_path = changed_path.decode('utf-8')
                changed.append(changed_path)

        # wait on the command to finish so we can get the
        # returncode/stderr output
        data = p.communicate()
        if p.returncode != 0:
            err_mesg = data[1]
            if sys.stderr.encoding:
                err_mesg =err_mesg.decode(sys.stderr.encoding,
                                          'backslashreplace')
            sys.stderr.write(err_mesg)
            sys.exit(2)

        return changed

    def user_command(self, section, repo, txn, fn):
        """ Run the command defined for a given section.
        Replaces $REPO, $TXN and $FILE with the repo, txn and fn arguments
        in the defined command.

        Returns a tuple of the exit code and the stderr output of the command"""
        cmd = self.config.get(section, 'command')
        cmd_env = os.environ.copy()
        cmd_env['REPO'] = repo
        cmd_env['TXN'] = txn
        cmd_env['FILE'] = fn
        p = subprocess.Popen(cmd, shell=True, env=cmd_env, stderr=subprocess.PIPE)
        data = p.communicate()
        err_mesg = data[1]
        if sys.stderr.encoding:
            err_mesg = err_mesg.decode(sys.stderr.encoding,
                                       'backslashreplace')
        return (p.returncode, err_mesg)

def main(repo, txn):
    exitcode = 0
    config = Config()
    config.read(os.path.join(repo, 'conf', 'validate-files.conf'))
    commands = Commands(config)

    rules = config.get_matching_rules(repo)

    # no matching rules so nothing to do
    if len(rules) == 0:
        sys.exit(0)

    changed = commands.svnlook_changed(repo, txn)
    # this shouldn't ever happen
    if len(changed) == 0:
        sys.exit(0)

    for rule in rules:
        section = config.get_rule_section_name(rule)
        pattern = config.get(section, 'pattern')

        # skip leading slashes if present in the pattern
        if pattern[0] == '/': pattern = pattern[1:]

        for fn in fnmatch.filter(changed, pattern):
            (returncode, err_mesg) = commands.user_command(section, repo,
                                                           txn, fn)
            if returncode != 0:
                sys.stderr.write(
                    "\nError validating file '%s' with rule '%s' " \
                    "(exit code %d):\n" % (fn, rule, returncode))
                sys.stderr.write(err_mesg)
                exitcode = 1

    return exitcode

if __name__ == "__main__":
    if len(sys.argv) != 3:
        sys.stderr.write("invalid args\n")
        sys.exit(0)

    try:
        sys.exit(main(sys.argv[1], sys.argv[2]))
    except configparser.Error as e:
        sys.stderr.write("Error with the validate-files.conf: %s\n" % e)
        sys.exit(2)
