""" FileReport module defines the FileReport class, to report file status to the transformation DB
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import copy

from DIRAC import S_OK
from DIRAC.Core.Utilities import DEncode
from DIRAC.TransformationSystem.Client.TransformationClient import TransformationClient
from DIRAC.RequestManagementSystem.Client.Operation import Operation

__RCSID__ = "$Id$"


class FileReport(object):
    """A stateful object for reporting to TransformationDB"""

    def __init__(self, server="Transformation/TransformationManager"):
        """c'tor

        self.transClient is a TransformationClient object
        """
        self.transClient = TransformationClient()
        self.transClient.setServer(server)
        self.statusDict = {}
        self.transformation = None
        self.force = False

    def setFileStatus(self, transformation, lfn, status, sendFlag=False):
        """Set file status in the context of the given transformation"""
        if not self.transformation:
            self.transformation = transformation
        if isinstance(lfn, (list, dict, tuple)):
            self.statusDict.update(dict.fromkeys(lfn, status))
        else:
            self.statusDict[lfn] = status
        if sendFlag:
            return self.commit()
        return S_OK()

    def setCommonStatus(self, status):
        """Set common status for all files in the internal cache"""
        for lfn in self.statusDict:
            self.statusDict[lfn] = status
        return S_OK()

    def getFiles(self):
        """Get the statuses of the files already accumulated in the FileReport object"""
        return copy.deepcopy(self.statusDict)

    def commit(self):
        """Commit pending file status update records"""
        if not self.statusDict:
            return S_OK({})

        result = self.transClient.setFileStatusForTransformation(self.transformation, self.statusDict, force=self.force)
        if result["OK"]:
            self.statusDict = {}
        return result

    def generateForwardDISET(self):
        """Commit the accumulated records and generate request eventually"""
        result = self.commit()
        commitOp = None
        if not result["OK"]:
            # Generate Request
            commitOp = Operation()
            commitOp.Type = "SetFileStatus"
            commitOp.Arguments = DEncode.encode(
                {"transformation": self.transformation, "statusDict": self.statusDict, "force": self.force}
            )

        return S_OK(commitOp)
