""" Accounting reporter
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import hashlib
import re

from DIRAC import S_OK, S_ERROR, gConfig
from DIRAC.Core.Utilities.ObjectLoader import loadObjects
from DIRAC.ConfigurationSystem.Client.PathFinder import getServiceSection
from DIRAC.AccountingSystem.private.Policies import gPoliciesList
from DIRAC.AccountingSystem.private.Plotters.BaseReporter import BaseReporter as myBaseReporter


class PlottersList(object):
    def __init__(self):
        objectsLoaded = loadObjects(
            "AccountingSystem/private/Plotters", re.compile(r".*[a-z1-9]Plotter\.py$"), myBaseReporter
        )
        self.__plotters = {}
        for objName in objectsLoaded:
            self.__plotters[objName[:-7]] = objectsLoaded[objName]

    def getPlotterClass(self, typeName):
        try:
            return self.__plotters[typeName]
        except KeyError:
            return None


class MainReporter(object):
    def __init__(self, db, setup):
        self._db = db
        self.setup = setup
        self.csSection = getServiceSection("Accounting/ReportGenerator", setup=setup)
        self.plotterList = PlottersList()

    def __calculateReportHash(self, reportRequest):
        requestToHash = dict(reportRequest)
        granularity = gConfig.getValue("%s/CacheTimeGranularity" % self.csSection, 300)
        for key in ("startTime", "endTime"):
            epoch = requestToHash[key]
            requestToHash[key] = epoch - epoch % granularity
        md5Hash = hashlib.md5()
        md5Hash.update(repr(requestToHash).encode())
        md5Hash.update(self.setup.encode())
        return md5Hash.hexdigest()

    def generate(self, reportRequest, credDict):
        typeName = reportRequest["typeName"]
        plotterClass = self.plotterList.getPlotterClass(typeName)
        if not plotterClass:
            return S_ERROR("There's no reporter registered for type %s" % typeName)
        if typeName in gPoliciesList:
            retVal = gPoliciesList[typeName].checkRequest(
                reportRequest["reportName"], credDict, reportRequest["condDict"], reportRequest["grouping"]
            )
            if not retVal["OK"]:
                return retVal
        reportRequest["hash"] = self.__calculateReportHash(reportRequest)
        plotter = plotterClass(self._db, self.setup, reportRequest["extraArgs"])
        return plotter.generate(reportRequest)

    def list(self, typeName):
        plotterClass = self.plotterList.getPlotterClass(typeName)
        if not plotterClass:
            return S_ERROR("There's no plotter registered for type %s" % typeName)
        plotter = plotterClass(self._db, self.setup)
        return S_OK(plotter.plotsList())
