#    Copyright 2015-2017 ARM Limited, Google and contributors
#
# Licensed 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.
#

import os
import shutil
import sys
import unittest
import utils_tests
import trappy
from trappy.ftrace import GenericFTrace

class TestCaching(utils_tests.SetupDirectory):
    def __init__(self, *args, **kwargs):
        super(TestCaching, self).__init__(
            [("trace_sched.txt", "trace.txt"),
             ("trace_sched.txt", "trace.raw.txt")],
            *args,
            **kwargs)

    def test_cache_created(self):
        """Test cache creation when enabled"""
        GenericFTrace.disable_cache = False
        trace = trappy.FTrace()

        trace_path = os.path.abspath(trace.trace_path)
        trace_dir = os.path.dirname(trace_path)
        trace_file = os.path.basename(trace_path)
        cache_dir = '.' + trace_file + '.cache'

        self.assertTrue(cache_dir in os.listdir(trace_dir))

    def test_cache_not_created(self):
        """Test that cache should not be created when disabled """
        GenericFTrace.disable_cache = True
        trace = trappy.FTrace()

        trace_path = os.path.abspath(trace.trace_path)
        trace_dir = os.path.dirname(trace_path)
        trace_file = os.path.basename(trace_path)
        cache_dir = '.' + trace_file + '.cache'

        self.assertFalse(cache_dir in os.listdir(trace_dir))

    def test_compare_cached_vs_uncached(self):
        """ Test that the cached and uncached traces are same """
        # Build the cache, but the actual trace will be parsed
        # fresh since this is a first time parse
        GenericFTrace.disable_cache = False
        uncached_trace = trappy.FTrace()
        uncached_dfr = uncached_trace.sched_wakeup.data_frame

        # Now read from previously parsed cache by reusing the path
        cached_trace = trappy.FTrace(uncached_trace.trace_path)
        cached_dfr = cached_trace.sched_wakeup.data_frame

        # Test whether timestamps are the same:
        # The cached/uncached versions of the timestamps are slightly
        # different due to floating point precision errors due to converting
        # back and forth CSV and DataFrame. For all purposes this is not relevant
        # since such rounding doesn't effect the end result.
        # Here's an example of the error, the actual normalized time when
        # calculated by hand is 0.081489, however following is what's stored
        # in the CSV for sched_wakeup events in this trace.
        # When converting the index to strings (and also what's in the CSV)
        # cached: ['0.0814890000001', '1.981491']
        # uncached: ['0.0814890000001', '1.981491']
        #
        # Keeping index as numpy.float64
        # cached: [0.081489000000100009, 1.9814909999999999]
        # uncached: [0.081489000000146916, 1.9814909999995507]
        #
        # To make it possible to test, lets just convert the timestamps to strings
        # and compare them below.

        cached_times = [str(r[0]) for r in cached_dfr.iterrows()]
        uncached_times = [str(r[0]) for r in uncached_dfr.iterrows()]

        self.assertTrue(cached_times == uncached_times)

        # compare other columns as well
        self.assertTrue([r[1].pid for r in cached_dfr.iterrows()] ==
                        [r[1].pid for r in uncached_dfr.iterrows()])

        self.assertTrue([r[1].comm for r in cached_dfr.iterrows()] ==
                        [r[1].comm for r in uncached_dfr.iterrows()])

        self.assertTrue([r[1].prio for r in cached_dfr.iterrows()] ==
                        [r[1].prio for r in uncached_dfr.iterrows()])

    def test_invalid_cache_overwritten(self):
        """Test a cache with a bad checksum is overwritten"""
        # This is a directory so we can't use the files_to_copy arg of
        # SetUpDirectory, just do it ourselves.
        cache_path = ".trace.txt.cache"
        src = os.path.join(utils_tests.TESTS_DIRECTORY, "trace_sched.txt.cache")
        shutil.copytree(src, cache_path)

        md5_path = os.path.join(cache_path, "md5sum")
        def read_md5sum():
            with open(md5_path) as f:
                return f.read()

        # Change 1 character of the stored checksum
        md5sum = read_md5sum()
        # Sorry, I guess modifying strings in Python is kind of awkward?
        md5sum_inc = "".join(list(md5sum[:-1]) + [chr(ord(md5sum[-1]) + 1)])
        with open(md5_path, "w") as f:
            f.write(md5sum_inc)

        # Parse a trace, this should delete and overwrite the invalidated cache
        GenericFTrace.disable_cache = False
        trace = trappy.FTrace()

        # Check that the modified md5sum was overwritten
        self.assertNotEqual(read_md5sum(), md5sum_inc,
                            "The invalid ftrace cache wasn't overwritten")

    def test_cache_dynamic_events(self):
        """Test that caching works if new event parsers have been registered"""

        # Parse the trace to create a cache
        GenericFTrace.disable_cache = False
        trace1 = trappy.FTrace()

        # Check we're actually testing what we think we are
        if hasattr(trace1, 'dynamic_event'):
            raise RuntimeError('Test bug: found unexpected event in trace')

        # Now register a new event type, call the constructor again, and check
        # that the newly added event (which is not present in the cache) is
        # parsed.

        parse_class = trappy.register_dynamic_ftrace("DynamicEvent", "dynamic_test_key")

        trace2 = trappy.FTrace()
        self.assertTrue(len(trace2.dynamic_event.data_frame) == 1)

        trappy.unregister_dynamic_ftrace(parse_class)

    def test_cache_normalize_time(self):
        """Test that caching doesn't break normalize_time"""
        GenericFTrace.disable_cache = False

        # Times in trace_sched.txt
        start_time = 6550.018511
        first_freq_event_time = 6550.056870

        # Parse without normalizing time
        trace1 = trappy.FTrace(events=['cpu_frequency', 'sched_wakeup'],
                               normalize_time=False)

        self.assertEqual(trace1.cpu_frequency.data_frame.index[0],
                         first_freq_event_time)

        # Parse with normalized time
        trace2 = trappy.FTrace(events=['cpu_frequency', 'sched_wakeup'],
                               normalize_time=True)

        self.assertEqual(trace2.cpu_frequency.data_frame.index[0],
                         first_freq_event_time - start_time)

    def test_cache_window(self):
        """Test that caching doesn't break the 'window' parameter"""
        GenericFTrace.disable_cache = False

        trace1 = trappy.FTrace(
            events=['sched_wakeup'],
            window=(0, 1))

        # Check that we're testing what we think we're testing The trace
        # contains 2 sched_wakeup events; this window should get rid of one of
        # them.
        if len(trace1.sched_wakeup.data_frame) != 1:
            raise RuntimeError('Test bug: bad sched_wakeup event count')

        # Parse again without the window
        trace1 = trappy.FTrace(
            events=['sched_wakeup'],
            window=(0, None))

        self.assertEqual(len(trace1.sched_wakeup.data_frame), 2)

    def test_cache_delete_single(self):
        GenericFTrace.disable_cache = False
        trace = trappy.FTrace()

        trace_path = os.path.abspath(trace.trace_path)
        trace_dir = os.path.dirname(trace_path)
        trace_file = os.path.basename(trace_path)
        cache_dir = '.' + trace_file + '.cache'
        number_of_trace_categories = 29
        self.assertEquals(len(os.listdir(cache_dir)), number_of_trace_categories)

        os.remove(os.path.join(cache_dir, 'SchedWakeup.csv'))
        self.assertEquals(len(os.listdir(cache_dir)), number_of_trace_categories - 1)

        # Generate trace again, should regenerate only the missing item
        trace = trappy.FTrace()
        self.assertEquals(len(os.listdir(cache_dir)), number_of_trace_categories)
        for c in trace.trace_classes:
            if isinstance(c, trace.class_definitions['sched_wakeup']):
                self.assertEquals(c.cached, False)
                continue
            self.assertEquals(c.cached, True)
