"""
:mod: DataIntegrityHandler


.. module: DataIntegrityHandler

  :synopsis: DataIntegrityHandler is the implementation of the Data Integrity service in
  the DISET framework

"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

# imports
import six

# from DIRAC
from DIRAC import S_OK
from DIRAC.Core.DISET.RequestHandler import RequestHandler
from DIRAC.DataManagementSystem.DB.DataIntegrityDB import DataIntegrityDB

__RCSID__ = "$Id$"


class DataIntegrityHandler(RequestHandler):
  """
  .. class:: DataIntegrityHandler

  Implementation of the Data Integrity service in the DISET framework.
  """

  @classmethod
  def initializeHandler(cls, serviceInfoDict):
    """ Initialization of DB object
    """

    cls.dataIntegrityDB = DataIntegrityDB()
    return S_OK()

  types_removeProblematic = [list(six.integer_types) + [list]]

  def export_removeProblematic(self, fileID):
    """ Remove the file with the supplied FileID from the database
    """
    if isinstance(fileID, list):
      fileIDs = fileID
    else:
      fileIDs = [int(fileID)]
    self.log.info("DataIntegrityHandler.removeProblematic: Attempting to remove problematic.")
    res = self.dataIntegrityDB.removeProblematic(fileIDs)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.removeProblematic: Failed to remove problematic.", res['Message'])
    return res

  types_getProblematic = []

  def export_getProblematic(self):
    """ Get the next problematic to resolve from the IntegrityDB
    """
    self.log.info("DataIntegrityHandler.getProblematic: Getting file to resolve.")
    res = self.dataIntegrityDB.getProblematic()
    if not res['OK']:
      self.log.error("DataIntegrityHandler.getProblematic: Failed to get problematic file to resolve.", res['Message'])
    return res

  types_getPrognosisProblematics = [list(six.string_types)]

  def export_getPrognosisProblematics(self, prognosis):
    """ Get problematic files from the problematics table of the IntegrityDB
    """
    self.log.info("DataIntegrityHandler.getPrognosisProblematics: Getting files with %s prognosis." % prognosis)
    res = self.dataIntegrityDB.getPrognosisProblematics(prognosis)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.getPrognosisProblematics: Failed to get prognosis files.", res['Message'])
    return res

  types_setProblematicStatus = [list(six.integer_types), list(six.string_types)]

  def export_setProblematicStatus(self, fileID, status):
    """ Update the status of the problematics with the provided fileID
    """
    self.log.info("DataIntegrityHandler.setProblematicStatus: Setting file %s status to %s." % (fileID, status))
    res = self.dataIntegrityDB.setProblematicStatus(fileID, status)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.setProblematicStatus: Failed to set status.", res['Message'])
    return res

  types_incrementProblematicRetry = [list(six.integer_types)]

  def export_incrementProblematicRetry(self, fileID):
    """ Update the retry count for supplied file ID.
    """
    self.log.info("DataIntegrityHandler.incrementProblematicRetry: Incrementing retries for file %s." % (fileID))
    res = self.dataIntegrityDB.incrementProblematicRetry(fileID)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.incrementProblematicRetry: Failed to increment retries.", res['Message'])
    return res

  types_insertProblematic = [list(six.string_types), dict]

  def export_insertProblematic(self, source, fileMetadata):
    """ Insert problematic files into the problematics table of the IntegrityDB
    """
    self.log.info("DataIntegrityHandler.insertProblematic: Inserting problematic file to integrity DB.")
    res = self.dataIntegrityDB.insertProblematic(source, fileMetadata)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.insertProblematic: Failed to insert.", res['Message'])
    return res

  types_changeProblematicPrognosis = []

  def export_changeProblematicPrognosis(self, fileID, newPrognosis):
    """ Change the prognosis for the supplied file """
    self.log.info("DataIntegrityHandler.changeProblematicPrognosis: Changing problematic prognosis.")
    res = self.dataIntegrityDB.changeProblematicPrognosis(fileID, newPrognosis)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.changeProblematicPrognosis: Failed to update.", res['Message'])
    return res

  types_getTransformationProblematics = [list(six.integer_types)]

  def export_getTransformationProblematics(self, transID):
    """ Get the problematics for a given transformation """
    self.log.info("DataIntegrityHandler.getTransformationProblematics: Getting problematics for transformation.")
    res = self.dataIntegrityDB.getTransformationProblematics(transID)
    if not res['OK']:
      self.log.error("DataIntegrityHandler.getTransformationProblematics: Failed.", res['Message'])
    return res

  types_getProblematicsSummary = []

  def export_getProblematicsSummary(self):
    """ Get a summary from the Problematics table from the IntegrityDB
    """
    self.log.info("DataIntegrityHandler.getProblematicsSummary: Getting problematics summary.")
    res = self.dataIntegrityDB.getProblematicsSummary()
    if res['OK']:
      for prognosis, statusDict in res['Value'].items():
        self.log.info("DataIntegrityHandler.getProblematicsSummary: %s." % prognosis)
        for status, count in statusDict.items():
          self.log.info("DataIntegrityHandler.getProblematicsSummary: \t%-10s %-10s." % (status, str(count)))
    else:
      self.log.error("DataIntegrityHandler.getProblematicsSummary: Failed to get summary.", res['Message'])
    return res

  types_getDistinctPrognosis = []

  def export_getDistinctPrognosis(self):
    """ Get a list of the distinct prognosis from the IntegrityDB
    """
    self.log.info("DataIntegrityHandler.getDistinctPrognosis: Getting distinct prognosis.")
    res = self.dataIntegrityDB.getDistinctPrognosis()
    if res['OK']:
      for prognosis in res['Value']:
        self.log.info("DataIntegrityHandler.getDistinctPrognosis: \t%s." % prognosis)
    else:
      self.log.error("DataIntegrityHandler.getDistinctPrognosis: Failed to get unique prognosis.", res['Message'])
    return res
