#!/usr/bin/env python2.7
#
# Copyright (c) 2016 ARM Limited
# All rights reserved
#
# The license below extends only to copyright in the software and shall
# not be construed as granting a license to any other intellectual
# property including but not limited to intellectual property relating
# to a hardware implementation of the functionality of the software
# licensed hereunder.  You may use the software subject to the license
# terms below provided that you ensure that this notice is replicated
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Authors: Andreas Sandberg

from __future__ import print_function

import subprocess
from threading import Timer
import time
import re

class CallTimeoutException(Exception):
    """Exception that indicates that a process call timed out"""

    def __init__(self, status, stdout, stderr):
        self.status = status
        self.stdout = stdout
        self.stderr = stderr

class ProcessHelper(subprocess.Popen):
    """Helper class to run child processes.

    This class wraps a subprocess.Popen class and adds support for
    using it in a with block. When the process goes out of scope, it's
    automatically terminated.

    with ProcessHelper(["/bin/ls"], stdout=subprocess.PIPE) as p:
        return p.call()
    """
    def __init__(self, *args, **kwargs):
        super(ProcessHelper, self).__init__(*args, **kwargs)

    def _terminate_nicely(self, timeout=5):
        def on_timeout():
            self.kill()

        if self.returncode is not None:
            return self.returncode

        timer = Timer(timeout, on_timeout)
        self.terminate()
        status = self.wait()
        timer.cancel()

        return status

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        if self.returncode is None:
            self._terminate_nicely()

    def call(self, timeout=0):
        self._timeout = False
        def on_timeout():
            self._timeout = True
            self._terminate_nicely()

        status, stdout, stderr = None, None, None
        timer = Timer(timeout, on_timeout)
        if timeout:
            timer.start()

        stdout, stderr = self.communicate()
        status = self.wait()

        timer.cancel()

        if self._timeout:
            self._terminate_nicely()
            raise CallTimeoutException(self.returncode, stdout, stderr)
        else:
            return status, stdout, stderr

class FileIgnoreList(object):
    """Helper class to implement file ignore lists.

    This class implements ignore lists using plain string matching and
    regular expressions. In the simplest use case, rules are created
    statically upon initialization:

        ignore_list = FileIgnoreList(name=("ignore_me.txt", ), rex=(r".*~", )

    Ignores can be queried using in the same ways as normal Python
    containers:

        if file_name in ignore_list:
            print "Ignoring %s" % file_name


    New rules can be added at runtime by extending the list in the
    rules attribute:

        ignore_list.rules.append(FileIgnoreList.simple("bar.txt"))
    """

    @staticmethod
    def simple(r):
        return lambda f: f == r

    @staticmethod
    def rex(r):
        re_obj = r if hasattr(r, "search") else re.compile(r)
        return lambda name: re_obj.search(name)

    def __init__(self, names=(), rex=()):
        self.rules = [ FileIgnoreList.simple(n) for n in names ] + \
                     [ FileIgnoreList.rex(r) for r in rex ]

    def __contains__(self, name):
        for rule in self.rules:
            if rule(name):
                return True
        return False

if __name__ == "__main__":
    # Run internal self tests to ensure that the helpers are working
    # properly. The expected output when running this script is
    # "SUCCESS!".

    cmd_foo = [ "/bin/echo", "-n", "foo" ]
    cmd_sleep = [ "/bin/sleep", "10" ]

    # Test that things don't break if the process hasn't been started
    with ProcessHelper(cmd_foo) as p:
        pass

    with ProcessHelper(cmd_foo, stdout=subprocess.PIPE) as p:
        status, stdout, stderr = p.call()
    assert stdout == "foo"
    assert status == 0

    try:
        with ProcessHelper(cmd_sleep) as p:
            status, stdout, stderr = p.call(timeout=1)
        assert False, "Timeout not triggered"
    except CallTimeoutException:
        pass

    ignore_list = FileIgnoreList(
        names=("ignore.txt", "foo/test.txt"),
        rex=(r"~$", re.compile("^#")))

    assert "ignore.txt" in ignore_list
    assert "bar.txt" not in ignore_list
    assert "foo/test.txt" in ignore_list
    assert "test.txt" not in ignore_list
    assert "file1.c~" in ignore_list
    assert "file1.c" not in ignore_list
    assert "#foo" in ignore_list
    assert "foo#" not in ignore_list

    ignore_list.rules.append(FileIgnoreList.simple("bar.txt"))
    assert "bar.txt" in ignore_list

    print("SUCCESS!")
