#!/usr/bin/python

#    Parse usage data from rrd's
#    Copyright (C) 2012  Anish Mangal <anish@activitycentral.com>
#
#    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 os
import re
from collections import defaultdict

import rrdtool

class StatsParser:
    def __init__(self, path):
        self._path = path
        self._activity_stats = defaultdict(lambda: defaultdict(dict))
        self._system_stats = defaultdict(lambda: defaultdict(dict))
        self._journal_stats = defaultdict(lambda: defaultdict(dict))
        self._activity_re = re.compile('^activity\..*\.rrd$')
        self._system_re = re.compile('system.rrd')
        self._journal_re = re.compile('journal.rrd')

    def get_path(self):
        return self._path

    def process_stats(self):
        self._parse_stats()

        # Lets just prettyprint the stats for now and decide what needs
        # to be done later
        for activity, activity_data in self._activity_stats.iteritems():
            total_active = 0
            print '==Activity:%s==' % activity
            for user, data in activity_data.iteritems():
                print 'user: %s: active: %d' % (user, data['active'])
                total_active += data['active']
            print '\n'

        # Do the same for journal and system uptime as well
        print '==Journal \'active\' stats=='
        for journal, journal_data in self._journal_stats.iteritems():
            total_active = 0
            for user, data in journal_data.iteritems():
                print 'user: %s: active: %d' % (user, data['active'])
                total_active += data['active']
            print '\n'

        # Do the same for system and system uptime as well
        print '==System \'uptime\' stats=='
        for system, system_data in self._system_stats.iteritems():
            total_uptime = 0
            for user, data in system_data.iteritems():
                print 'user: %s: uptime: %d' % (user, data['uptime'])
                total_uptime += data['uptime']
            print '\n'


    def _parse_stats(self):
        # We are just collecting per user stats here:
        # Activities: active
        # Journal: active
        # System: uptime
        for root, dirnames, filenames in os.walk(self._path):
            if len(filenames) > 0:
                for filename in filenames:
                    if self._activity_re.match(filename) is not None:
                        self._activity_stats[filename][root]['active'] =\
                            self._get_stats(os.path.join(root,
                                filename), 'active')
                    if self._system_re.match(filename) is not None:
                        self._system_stats[filename][root]['uptime'] =\
                            self._get_stats(os.path.join(root,
                                filename), 'uptime')
                    if self._journal_re.match(filename) is not None:
                        self._journal_stats[filename][root]['active'] =\
                            self._get_stats(os.path.join(root,
                                filename), 'active')

        #print self._system_stats
        #print self._journal_stats
        #print self._activity_stats

    def _find_cumulative_value(self, key_values_list):
        if sum(key_values_list) == 0:
            return 0
        else:
            for i in range(1, len(key_values_list)):
                if key_values_list[i] > key_values_list[i - 1]:
                    key_values_list[i - 1] = 0

            return sum(key_values_list)

    def _get_stats(self, path, key):
        assert os.path.exists(path) == True

        # This will return a tuple of tuples and lists in the following
        # form:
        # ((start, stop, step),
        #  (key1, key2, ... keyN)
        #  [(key1_val1, key2_val1, ... keyN_val1),
        #   (key1_val2, key2_val2, ... keyN_val2)
        #    ...
        #   (key1_valM, key2_valM, ... keyN_valM)]
        # )
        raw_rrd_data = rrdtool.fetch(path, '--start', 'now-7d',\
                '--end', 'now', 'AVERAGE')
        key_index = None
        # Find out which keyid = key from our raw data above
        for i in range(len(raw_rrd_data[1])):
            if raw_rrd_data[1][i] == key:
                key_index = i

        #print 'Index for key:%s is %d' % (key, key_index)

        if key_index == None:
            print 'ERROR, %s key not found, exiting' % key
            return -1

        key_values_list = []
        i = 0
        for values_tuple in raw_rrd_data[2]:
            data = values_tuple[key_index]
            if data == None:
                key_values_list.append(0)
            else:
                key_values_list.append(int(data))

        return self._find_cumulative_value(key_values_list)

if __name__ == '__main__':
    stats_parser = StatsParser('/var/lib/sugar-stats/rrd/')
    print 'Parsing stats at %s' % stats_parser.get_path()
    stats_parser.process_stats()

