#!/usr/bin/env python

import cherrypy
import json
import os

from dm.common.constants import dmProcessingMode
from dm.common.constants import dmProcessingStatus
from dm.common.service.dmSessionController import DmSessionController
from dm.common.exceptions.invalidRequest import InvalidRequest
from dm.common.utility.encoder import Encoder
from dm.common.utility.dictUtility import DictUtility

from dm.daq_web_service.service.impl.experimentSessionControllerImpl import ExperimentSessionControllerImpl


class ExperimentSessionController(DmSessionController):

    def __init__(self):
        DmSessionController.__init__(self)
        self.experimentSessionControllerImpl = ExperimentSessionControllerImpl()

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def startDaq(self, experimentName, dataDirectory, **kwargs):
        if not experimentName:
            raise InvalidRequest('Missing experiment name.')
        experimentName = Encoder.decode(experimentName)
        if not dataDirectory:
            raise InvalidRequest('Missing data directory.')
        dataDirectory = Encoder.decode(dataDirectory)
        if not dataDirectory.startswith('/') and not dataDirectory.count('://'):
            raise InvalidRequest('Data directory must be an absolute path.')

        daqInfo = {}
        encodedDaqInfo = kwargs.get('daqInfo')
        if encodedDaqInfo is not None:
            daqInfo = json.loads(Encoder.decode(encodedDaqInfo))
        response = self.experimentSessionControllerImpl.startDaq(experimentName, dataDirectory, daqInfo).getFullJsonRep()
        self.logger.debug('Returning: %s' % response)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def stopDaq(self, experimentName, dataDirectory, **kwargs):
        if not experimentName:
            raise InvalidRequest('Missing experiment name.')
        experimentName = Encoder.decode(experimentName)
        if not dataDirectory:
            raise InvalidRequest('Missing data directory.')
        dataDirectory = Encoder.decode(dataDirectory)
        response = self.experimentSessionControllerImpl.stopDaq(experimentName, dataDirectory).getFullJsonRep()
        self.logger.debug('Returning: %s' % response)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def getDaqInfo(self, id, **kwargs):
        response = self.experimentSessionControllerImpl.getDaqInfo(id).getFullJsonRep()
        self.logger.debug('Returning: %s' % response)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def listDaqs(self, status=dmProcessingStatus.DM_PROCESSING_STATUS_ANY, **kwargs):
        if not status:
            status = dmProcessingStatus.DM_PROCESSING_STATUS_ANY
        if status not in dmProcessingStatus.DM_ALLOWED_PROCESSING_STATUS_LIST:
            raise InvalidRequest('Invalid processing status "%s". Status must be one of %s.' % (status,dmProcessingStatus.DM_ALLOWED_PROCESSING_STATUS_LIST))
        return self.listToJson(self.experimentSessionControllerImpl.listDaqs(status))

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def upload(self, experimentName, dataDirectory, **kwargs):
        if not experimentName:
            raise InvalidRequest('Missing experiment name.')
        experimentName = Encoder.decode(experimentName)
        if not dataDirectory:
            raise InvalidRequest('Missing data directory.')
        dataDirectory = Encoder.decode(dataDirectory)
        if not dataDirectory.startswith('/') and not dataDirectory.count('://'):
            raise InvalidRequest('Data directory must be an absolute path.')

        daqInfo = {}
        encodedDaqInfo = kwargs.get('daqInfo')
        if encodedDaqInfo:
            daqInfo = json.loads(Encoder.decode(encodedDaqInfo))
        processingMode = DictUtility.getAndRemoveKey(daqInfo, 'processingMode', dmProcessingMode.DM_PROCESSING_MODE_FILES)
        if processingMode not in dmProcessingMode.DM_ALLOWED_PROCESSING_MODE_LIST:
            raise InvalidRequest('Allowed processing modes: %s' % dmProcessingMode.DM_ALLOWED_PROCESSING_MODE_LIST)
        if processingMode == dmProcessingMode.DM_PROCESSING_MODE_FILES:
            response = self.experimentSessionControllerImpl.uploadFiles(experimentName, dataDirectory, daqInfo).getFullJsonRep()
        else:
            response = self.experimentSessionControllerImpl.uploadDirectory(experimentName, dataDirectory, daqInfo).getFullJsonRep()
        self.logger.debug('Returning upload info for directory %s' % dataDirectory)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def getUploadInfo(self, id, **kwargs):
        response = self.experimentSessionControllerImpl.getUploadInfo(id).getFullJsonRep()
        self.logger.debug('Returning info for upload id %s' % id)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def listUploads(self, status=dmProcessingStatus.DM_PROCESSING_STATUS_ANY, **kwargs):
        if not status:
            status = dmProcessingStatus.DM_PROCESSING_STATUS_ANY
        if status not in dmProcessingStatus.DM_ALLOWED_PROCESSING_STATUS_LIST:
            raise InvalidRequest('Invalid processing status "%s". Status must be one of %s.' % (status,dmProcessingStatus.DM_ALLOWED_PROCESSING_STATUS_LIST))
        return self.listToJson(self.experimentSessionControllerImpl.listUploads(status))

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def stopUpload(self, id, **kwargs):
        response = self.experimentSessionControllerImpl.stopUpload(id).getFullJsonRep()
        self.logger.debug('Stopped upload id %s' % id)
        return response

    @cherrypy.expose
    @DmSessionController.require(DmSessionController.isAdministrator())
    @DmSessionController.execute
    def getProcessingPlugins(self, **kwargs):
        return self.listToJson(self.experimentSessionControllerImpl.getProcessingPlugins())