# Copyright (C) 2013-2022 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import time
import os
import gc
import sys

# time.perf_counter() and time.process_time() were added in Python
# 3.3, time.clock() was removed in Python 3.8.
if sys.version_info < (3, 3, 0):
    time.perf_counter = time.clock
    time.process_time = time.clock


class Measure(object):
    """A class that measure and collect the interesting data for a given testcase.

    An instance of Measure has a collection of measurements, and each
    of them is to measure a given aspect, such as time and memory.
    """

    def __init__(self, measurements):
        """Constructor of measure.

        measurements is a collection of Measurement objects.
        """

        self.measurements = measurements

    def measure(self, func, id):
        """Measure the operations done by func with a collection of measurements."""
        # Enable GC, force GC and disable GC before running test in order to reduce
        # the interference from GC.
        gc.enable()
        gc.collect()
        gc.disable()

        for m in self.measurements:
            m.start(id)

        func()

        for m in self.measurements:
            m.stop(id)

        gc.enable()

    def report(self, reporter, name):
        """Report the measured results."""
        for m in self.measurements:
            m.report(reporter, name)


class Measurement(object):
    """A measurement for a certain aspect."""

    def __init__(self, name, result):
        """Constructor of Measurement.

        Attribute result is the TestResult associated with measurement.
        """
        self.name = name
        self.result = result

    def start(self, id):
        """Abstract method to start the measurement."""
        raise NotImplementedError("Abstract Method:start")

    def stop(self, id):
        """Abstract method to stop the measurement.

        When the measurement is stopped, we've got something, and
        record them in result.
        """
        raise NotImplementedError("Abstract Method:stop.")

    def report(self, reporter, name):
        """Report the measured data by argument reporter."""
        self.result.report(reporter, name + " " + self.name)


class MeasurementPerfCounter(Measurement):
    """Measurement on performance counter."""

    # Measures time in fractional seconds, using a performance
    # counter, i.e. a clock with the highest available resolution to
    # measure a short duration.  It includes time elapsed during sleep
    # and is system-wide.

    def __init__(self, result):
        super(MeasurementPerfCounter, self).__init__("perf_counter", result)
        self.start_time = 0

    def start(self, id):
        self.start_time = time.perf_counter()

    def stop(self, id):
        perf_counter = time.perf_counter() - self.start_time
        self.result.record(id, perf_counter)


class MeasurementProcessTime(Measurement):
    """Measurement on process time."""

    # Measures the sum of the system and user CPU time of the current
    # process.  Does not include time elapsed during sleep.  It is
    # process-wide by definition.

    def __init__(self, result):
        super(MeasurementProcessTime, self).__init__("process_time", result)
        self.start_time = 0

    def start(self, id):
        self.start_time = time.process_time()

    def stop(self, id):
        process_time = time.process_time() - self.start_time
        self.result.record(id, process_time)


class MeasurementWallTime(Measurement):
    """Measurement on Wall time."""

    def __init__(self, result):
        super(MeasurementWallTime, self).__init__("wall_time", result)
        self.start_time = 0

    def start(self, id):
        self.start_time = time.time()

    def stop(self, id):
        wall_time = time.time() - self.start_time
        self.result.record(id, wall_time)


class MeasurementVmSize(Measurement):
    """Measurement on memory usage represented by VmSize."""

    def __init__(self, result):
        super(MeasurementVmSize, self).__init__("vmsize", result)

    def _compute_process_memory_usage(self, key):
        file_path = "/proc/%d/status" % os.getpid()
        try:
            t = open(file_path)
            v = t.read()
            t.close()
        except:
            return 0
        i = v.index(key)
        v = v[i:].split(None, 3)
        if len(v) < 3:
            return 0
        return int(v[1])

    def start(self, id):
        pass

    def stop(self, id):
        memory_used = self._compute_process_memory_usage("VmSize:")
        self.result.record(id, memory_used)
