# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.


import os
import re
import sys

import mozinfo
import mozrunner.utils

def _raw_log():
    import logging
    return logging.getLogger(__name__)


# Do not add anything to this list, unless one of the existing leaks below
# has started to leak additional objects. This function returns a dict
# mapping the names of objects as reported to the XPCOM leak checker to an
# upper bound on the number of leaked objects of that kind that are allowed
# to appear in a content process leak report.
def expectedTabProcessLeakCounts():
    leaks = {}

    def appendExpectedLeakCounts(leaks2):
        for obj, count in leaks2.iteritems():
            leaks[obj] = leaks.get(obj, 0) + count

    # Bug 1117203 - ImageBridgeChild is not shut down in tab processes.
    appendExpectedLeakCounts({
        'AsyncTransactionTrackersHolder': 1,
        'CondVar': 2,
        'IPC::Channel': 1,
        'MessagePump': 1,
        'Mutex': 2,
        'PImageBridgeChild': 1,
        'RefCountedMonitor': 1,
        'RefCountedTask': 2,
        'StoreRef': 1,
        'WaitableEventKernel': 1,
        'WeakReference<MessageListener>': 1,
        'base::Thread': 1,
        'ipc::MessageChannel': 1,
        'nsTArray_base': 7,
        'nsThread': 1,
    })

    # Bug 1215265 - CompositorChild is not shut down.
    appendExpectedLeakCounts({
        'CompositorChild': 1,
        'CondVar': 1,
        'IPC::Channel': 1,
        'Mutex': 1,
        'PCompositorChild': 1,
        'RefCountedMonitor': 1,
        'RefCountedTask': 2,
        'StoreRef': 1,
        'WeakReference<MessageListener>': 1,
        'ipc::MessageChannel': 1,
        'nsTArray_base': 2,
    })

    # Bug 1219369 - On Aurora, we leak a SyncObject in Windows.
    appendExpectedLeakCounts({
        'SyncObject': 1
    })

    # Bug 1219916 - On Aurora, we leak textures and image containers
    # on Windows.
    appendExpectedLeakCounts({
        'AsyncTransactionTrackersHolder': 4,
        'CompositableChild': 4,
        'CondVar': 4,
        'Mutex': 8,
        'PCompositableChild': 4,
        'PImageContainerChild': 4,
        'PTextureChild': 4,
        'SharedMemory': 4,
        'TextureChild': 4,
        'TextureData': 4,
        'WeakReference<MessageListener>': 12,
    })

    return leaks


def process_single_leak_file(leakLogFileName, processType, leakThreshold,
                             ignoreMissingLeaks, log=None,
                             stackFixer=None):
    """Process a single leak log.
    """

    #     |              |Per-Inst  Leaked|     Total  Rem|
    #   0 |TOTAL         |      17     192| 419115886    2|
    # 833 |nsTimerImpl   |      60     120|     24726    2|
    # 930 |Foo<Bar, Bar> |      32       8|       100    1|
    lineRe = re.compile(r"^\s*\d+ \|"
                        r"(?P<name>[^|]+)\|"
                        r"\s*(?P<size>-?\d+)\s+(?P<bytesLeaked>-?\d+)\s*\|"
                        r"\s*-?\d+\s+(?P<numLeaked>-?\d+)")
    # The class name can contain spaces. We remove trailing whitespace later.

    log = log or _raw_log()

    processString = "%s process:" % processType
    expectedLeaks = expectedTabProcessLeakCounts() if processType == 'tab' else {}
    crashedOnPurpose = False
    totalBytesLeaked = None
    logAsWarning = False
    leakAnalysis = []
    leakedObjectAnalysis = []
    leakedObjectNames = []
    recordLeakedObjects = False
    with open(leakLogFileName, "r") as leaks:
        for line in leaks:
            if line.find("purposefully crash") > -1:
                crashedOnPurpose = True
            matches = lineRe.match(line)
            if not matches:
                # eg: the leak table header row
                strippedLine = line.rstrip()
                log.info(stackFixer(strippedLine) if stackFixer else strippedLine)
                continue
            name = matches.group("name").rstrip()
            size = int(matches.group("size"))
            bytesLeaked = int(matches.group("bytesLeaked"))
            numLeaked = int(matches.group("numLeaked"))
            # Output the raw line from the leak log table if it is the TOTAL row,
            # or is for an object row that has been leaked.
            if numLeaked != 0 or name == "TOTAL":
                log.info(line.rstrip())
            # Analyse the leak log, but output later or it will interrupt the
            # leak table
            if name == "TOTAL":
                # Multiple default processes can end up writing their bloat views into a single
                # log, particularly on B2G. Eventually, these should be split into multiple
                # logs (bug 1068869), but for now, we report the largest leak.
                if totalBytesLeaked != None:
                    leakAnalysis.append("WARNING | leakcheck | %s multiple BloatView byte totals found"
                                        % processString)
                else:
                    totalBytesLeaked = 0
                if bytesLeaked > totalBytesLeaked:
                    totalBytesLeaked = bytesLeaked
                    # Throw out the information we had about the previous bloat
                    # view.
                    leakedObjectNames = []
                    leakedObjectAnalysis = []
                    recordLeakedObjects = True
                else:
                    recordLeakedObjects = False
            if size < 0 or bytesLeaked < 0 or numLeaked < 0:
                leakAnalysis.append("TEST-UNEXPECTED-FAIL | leakcheck | %s negative leaks caught!"
                                    % processString)
                logAsWarning = True
                continue
            if name != "TOTAL" and numLeaked != 0 and recordLeakedObjects:
                currExpectedLeak = expectedLeaks.get(name, 0)
                if not expectedLeaks or numLeaked <= currExpectedLeak:
                    if not expectedLeaks:
                        leakedObjectNames.append(name)
                    leakedObjectAnalysis.append("TEST-INFO | leakcheck | %s leaked %d %s"
                                                % (processString, numLeaked, name))
                else:
                    leakedObjectNames.append(name)
                    leakedObjectAnalysis.append("WARNING | leakcheck | %s leaked too many %s (expected %d, got %d)"
                                                % (processString, name, currExpectedLeak, numLeaked))


    leakAnalysis.extend(leakedObjectAnalysis)
    if logAsWarning:
        log.warning('\n'.join(leakAnalysis))
    else:
        log.info('\n'.join(leakAnalysis))

    logAsWarning = False

    if totalBytesLeaked is None:
        # We didn't see a line with name 'TOTAL'
        if crashedOnPurpose:
            log.info("TEST-INFO | leakcheck | %s deliberate crash and thus no leak log"
                     % processString)
        elif ignoreMissingLeaks:
            log.info("TEST-INFO | leakcheck | %s ignoring missing output line for total leaks"
                     % processString)
        else:
            log.info("TEST-UNEXPECTED-FAIL | leakcheck | %s missing output line for total leaks!"
                     % processString)
            log.info("TEST-INFO | leakcheck | missing output line from log file %s"
                     % leakLogFileName)
        return

    if totalBytesLeaked == 0:
        log.info("TEST-PASS | leakcheck | %s no leaks detected!" %
                 processString)
        return

    if totalBytesLeaked > leakThreshold or (expectedLeaks and leakedObjectNames):
        logAsWarning = True
        # Fail the run if we're over the threshold (which defaults to 0)
        prefix = "TEST-UNEXPECTED-FAIL"
    else:
        prefix = "WARNING"
    # Create a comma delimited string of the first N leaked objects found,
    # to aid with bug summary matching in TBPL. Note: The order of the objects
    # had no significance (they're sorted alphabetically).
    maxSummaryObjects = 5
    leakedObjectSummary = ', '.join(leakedObjectNames[:maxSummaryObjects])
    if len(leakedObjectNames) > maxSummaryObjects:
        leakedObjectSummary += ', ...'

    # totalBytesLeaked will include any expected leaks, so it can be off
    # by a few thousand bytes.
    if logAsWarning:
        log.warning("%s | leakcheck | %s %d bytes leaked (%s)"
                    % (prefix, processString, totalBytesLeaked, leakedObjectSummary))
    else:
        log.info("%s | leakcheck | %s %d bytes leaked (%s)"
                 % (prefix, processString, totalBytesLeaked, leakedObjectSummary))


def process_leak_log(leak_log_file, leak_thresholds=None,
                     ignore_missing_leaks=None, log=None,
                     stack_fixer=None):
    """Process the leak log, including separate leak logs created
    by child processes.

    Use this function if you want an additional PASS/FAIL summary.
    It must be used with the |XPCOM_MEM_BLOAT_LOG| environment variable.

    The base of leak_log_file for a non-default process needs to end with
      _proctype_pid12345.log
    "proctype" is a string denoting the type of the process, which should
    be the result of calling XRE_ChildProcessTypeToString(). 12345 is
    a series of digits that is the pid for the process. The .log is
    optional.

    All other file names are treated as being for default processes.

    leak_thresholds should be a dict mapping process types to leak thresholds,
    in bytes. If a process type is not present in the dict the threshold
    will be 0.

    ignore_missing_leaks should be a list of process types. If a process
    creates a leak log without a TOTAL, then we report an error if it isn't
    in the list ignore_missing_leaks.
    """

    log = log or _raw_log()

    leakLogFile = leak_log_file
    if not os.path.exists(leakLogFile):
        log.info(
            "WARNING | leakcheck | refcount logging is off, so leaks can't be detected!")
        return

    leakThresholds = leak_thresholds or {}
    ignoreMissingLeaks = ignore_missing_leaks or []

    # This list is based on kGeckoProcessTypeString. ipdlunittest processes likely
    # are not going to produce leak logs we will ever see.
    knownProcessTypes = ["default", "plugin", "tab", "geckomediaplugin"]

    for processType in knownProcessTypes:
        log.info("TEST-INFO | leakcheck | %s process: leak threshold set at %d bytes"
                 % (processType, leakThresholds.get(processType, 0)))

    for processType in leakThresholds:
        if not processType in knownProcessTypes:
            log.info("TEST-UNEXPECTED-FAIL | leakcheck | Unknown process type %s in leakThresholds"
                     % processType)

    (leakLogFileDir, leakFileBase) = os.path.split(leakLogFile)
    if leakFileBase[-4:] == ".log":
        leakFileBase = leakFileBase[:-4]
        fileNameRegExp = re.compile(r"_([a-z]*)_pid\d*.log$")
    else:
        fileNameRegExp = re.compile(r"_([a-z]*)_pid\d*$")

    for fileName in os.listdir(leakLogFileDir):
        if fileName.find(leakFileBase) != -1:
            thisFile = os.path.join(leakLogFileDir, fileName)
            m = fileNameRegExp.search(fileName)
            if m:
                processType = m.group(1)
            else:
                processType = "default"
            if not processType in knownProcessTypes:
                log.info("TEST-UNEXPECTED-FAIL | leakcheck | Leak log with unknown process type %s"
                         % processType)
            leakThreshold = leakThresholds.get(processType, 0)
            process_single_leak_file(thisFile, processType, leakThreshold,
                                     processType in ignoreMissingLeaks,
                                     log=log, stackFixer=stack_fixer)
