'''
When extensions.
'''
#  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.

from autest.api import AddWhenFunction
import hosts.output as host
import os
import re


def FileContains(haystack, needle, desired_count=1):
    """
    Return whether the file haystack contains the string needle.

    Args:
        haystack (str): The path to the file to be inspected.
        needle (str): The content to look for in haystack. This can be a
            regular expression which will be used in Python's re.search
            function.
        desired_count (int): How many times the caller desires to see needle in
            haystack before considering the When condition fulfilled.

    Returns:
        True if the haystack exists as a file and contains needle, False
        otherwise.
    """

    if desired_count < 0:
        raise ValueError("Cannot pass a negative desired_count value to FileContains.")
    if desired_count == 0:
        raise ValueError("Cannot pass a desired_count of 0 to FileContains.")

    if not os.path.exists(haystack):
        host.WriteDebug(
            ['FileContains', 'when'], "Testing for file content '{0}' in file '{1}': file does not exist".format(needle, haystack))
        return False

    needle_regex = re.compile(needle)
    with open(haystack) as f:
        needle_seen_count = 0
        line_count = 0
        for line in f:
            line_count += 1
            if needle_regex.search(line):
                host.WriteDebug(
                    ['FileContains', 'when'], "Found '{0}' in file '{1}' in line: '{2}', line number: {3}".format(
                        needle, haystack, line.rstrip(), line_count))
                needle_seen_count += 1

                if needle_seen_count >= desired_count:
                    host.WriteDebug(
                        ['FileContains', 'when'], "Testing for file content '{0}' in file '{1}', "
                        "successfully found it the desired {2} times".format(needle, haystack, needle_seen_count))
                    return True

        host.WriteDebug(
            ['FileContains', 'when'], "Testing for file content '{0}' in file '{1}', only seen {2} "
            "out of the desired {3} times".format(needle, haystack, needle_seen_count, desired_count))

        return False


AddWhenFunction(FileContains)
