#!/usr/bin/env python
# -*- coding:utf-8 -*- 


##############################################################################
## license :
##============================================================================
##
## File :        PlexilPlanStorage.py
## 
## Project :     Plexil Plan Storage
##
## This file is part of Tango device class.
## 
## Tango 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.
## 
## Tango 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 Tango.  If not, see <http://www.gnu.org/licenses/>.
## 
##
## $Author :      dipankar1995$
##
## $Revision :    $
##
## $Date :        $
##
## $HeadUrl :     $
##============================================================================
##            This file is generated by POGO
##    (Program Obviously used to Generate tango Object)
##
##        (c) - Software Engineering Group - ESRF
##############################################################################

"""A Tango interface to store and retrieve Plexil plans."""

__all__ = ["PlexilPlanStorage", "PlexilPlanStorageClass", "main"]

__docformat__ = 'restructuredtext'

import PyTango
import sys
# Add additional import
#----- PROTECTED REGION ID(PlexilPlanStorage.additionnal_import) ENABLED START -----#
import os, subprocess
from PyTango import DevState
#----- PROTECTED REGION END -----#	//	PlexilPlanStorage.additionnal_import

## Device States Description
## No states for this device

class PlexilPlanStorage (PyTango.Device_4Impl):

    #--------- Add you global variables here --------------------------
    #----- PROTECTED REGION ID(PlexilPlanStorage.global_variables) ENABLED START -----#
    
    #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.global_variables

    def __init__(self,cl, name):
        PyTango.Device_4Impl.__init__(self,cl,name)
        self.debug_stream("In __init__()")
        PlexilPlanStorage.init_device(self)
        #----- PROTECTED REGION ID(PlexilPlanStorage.__init__) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.__init__
        
    def delete_device(self):
        self.debug_stream("In delete_device()")
        #----- PROTECTED REGION ID(PlexilPlanStorage.delete_device) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.delete_device

    def init_device(self):
        self.debug_stream("In init_device()")
        self.get_device_properties(self.get_device_class())
        self.attr_IsStorageDirEmpty_read = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.init_device) ENABLED START -----#
        self.set_state(DevState.ON);
        self.set_status("Ready to accept queries.");
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.init_device

    def always_executed_hook(self):
        self.debug_stream("In always_excuted_hook()")
        #----- PROTECTED REGION ID(PlexilPlanStorage.always_executed_hook) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.always_executed_hook

    #-----------------------------------------------------------------------------
    #    PlexilPlanStorage read/write attribute methods
    #-----------------------------------------------------------------------------
    
    def read_IsStorageDirEmpty(self, attr):
        self.debug_stream("In read_IsStorageDirEmpty()")
        #----- PROTECTED REGION ID(PlexilPlanStorage.IsStorageDirEmpty_read) ENABLED START -----#
        attr.set_value(False)
        path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
        if not os.listdir(path):
            attr.set_value(True)
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.IsStorageDirEmpty_read
        
    
    
        #----- PROTECTED REGION ID(PlexilPlanStorage.initialize_dynamic_attributes) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.initialize_dynamic_attributes
            
    def read_attr_hardware(self, data):
        self.debug_stream("In read_attr_hardware()")
        #----- PROTECTED REGION ID(PlexilPlanStorage.read_attr_hardware) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.read_attr_hardware


    #-----------------------------------------------------------------------------
    #    PlexilPlanStorage command methods
    #-----------------------------------------------------------------------------
    
    def AddPlan(self, argin):
        """ Adds a Plexil Plan to storage and tries to compile it.
        
        :param argin: sourcedestination
        :type: PyTango.DevString
        :return: result
        :rtype: PyTango.DevBoolean """
        self.debug_stream("In AddPlan()")
        argout = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.AddPlan) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            argin = argin.split(";")
            source, dest = argin[0], path + argin[1]
            command = 'cp' + ' ' + source + ' ' + dest
            val = subprocess.check_call(command, shell=True)
            if val == 0:
                argout = True
        except Exception as e:
            argout = False
            return argout
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.AddPlan
        return argout
        
    def AddConfigFile(self, argin):
        """ Adds a Plexil Debug Config File or a Plexil Interface Config File to the storage
        
        :param argin: sourcedestination
        :type: PyTango.DevString
        :return: result
        :rtype: PyTango.DevBoolean """
        self.debug_stream("In AddConfigFile()")
        argout = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.AddConfigFile) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            argin = argin.split(";")
            source, dest = argin[0], path + argin[1]
            command = 'cp' + ' ' + source + ' ' + dest
            val = subprocess.check_call(command, shell=True)
            if val == 0:
                argout = True
        except Exception as e:
            argout = False
            return argout     
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.AddConfigFile
        return argout
        
    def AddScript(self, argin):
        """ Adds a Plexil script file and tries to compile it
        
        :param argin: sourcedestination
        :type: PyTango.DevString
        :return: result
        :rtype: PyTango.DevBoolean """
        self.debug_stream("In AddScript()")
        argout = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.AddScript) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            argin = argin.split(";")
            source, dest = argin[0], path + argin[1]
            command = 'cp' + ' ' + source + ' ' + dest
            val = subprocess.check_call(command, shell=True)
            if val == 0:
                argout = True
        except Exception as e:
            argout = False
            return argout
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.AddScript
        return argout
        
    def DeleteFile(self, argin):
        """ Deletes the given file from storage - can be a plan, a script, a debug-config or a interface config
        
        :param argin: pathtofile
        :type: PyTango.DevString
        :return: result
        :rtype: PyTango.DevBoolean """
        self.debug_stream("In DeleteFile()")
        argout = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.DeleteFile) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            command = 'rm ' + path + argin
            val = subprocess.check_call(command, shell=True)
            if val == 0:
                argout = True
        except Exception as e:
            argout = False
            return argout
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.DeleteFile
        return argout
        
    def RetrieveFile(self, argin):
        """ Retreive the specified Plexil File to the specified location
        
        :param argin: sourcedestination
        :type: PyTango.DevString
        :return: result
        :rtype: PyTango.DevBoolean """
        self.debug_stream("In RetrieveFile()")
        argout = False
        #----- PROTECTED REGION ID(PlexilPlanStorage.RetrieveFile) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            argin = argin.split(";")
            source, dest = path + argin[0], argin[1]
            command = 'cp' + ' ' + source + ' ' + dest
            val = subprocess.check_call(command, shell=True)
            if val == 0:
                argout = True
        except Exception as e:
            argout = False
            return argout
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.RetrieveFile
        return argout
        
    def ListDir(self, argin):
        """ Do a `ls` command on the storage directory and pipe it to the specified path if any
        
        :param argin: lsdumppath
        :type: PyTango.DevString
        :return: 
        :rtype: PyTango.DevVoid """
        self.debug_stream("In ListDir()")
        #----- PROTECTED REGION ID(PlexilPlanStorage.ListDir) ENABLED START -----#
        try:
            path = PyTango.Database().get_class_property(sys.argv[0], "StorageDirPath")["StorageDirPath"][0]
            command = 'ls -l' + ' ' + path
            if argin != 'stdout':
                command = command + ' > ' + argin
            val = subprocess.check_call(command, shell=True)
            if val != 0:
                return
        except Exception as e:
            return
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.ListDir
        

class PlexilPlanStorageClass(PyTango.DeviceClass):
    #--------- Add you global class variables here --------------------------
    #----- PROTECTED REGION ID(PlexilPlanStorage.global_class_variables) ENABLED START -----#
    
    #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.global_class_variables

    def dyn_attr(self, dev_list):
        """Invoked to create dynamic attributes for the given devices.
        Default implementation calls
        :meth:`PlexilPlanStorage.initialize_dynamic_attributes` for each device
    
        :param dev_list: list of devices
        :type dev_list: :class:`PyTango.DeviceImpl`"""
    
        for dev in dev_list:
            try:
                dev.initialize_dynamic_attributes()
            except:
                import traceback
                dev.warn_stream("Failed to initialize dynamic attributes")
                dev.debug_stream("Details: " + traceback.format_exc())
        #----- PROTECTED REGION ID(PlexilPlanStorage.dyn_attr) ENABLED START -----#
        
        #----- PROTECTED REGION END -----#	//	PlexilPlanStorage.dyn_attr

    #    Class Properties
    class_property_list = {
        'StorageDirPath':
            [PyTango.DevString,
            "Path to the Plexil Storage Directory",
            ["/root/"] ],
        }


    #    Device Properties
    device_property_list = {
        }


    #    Command definitions
    cmd_list = {
        'AddPlan':
            [[PyTango.DevString, "sourcedestination"],
            [PyTango.DevBoolean, "result"]],
        'AddConfigFile':
            [[PyTango.DevString, "sourcedestination"],
            [PyTango.DevBoolean, "result"]],
        'AddScript':
            [[PyTango.DevString, "sourcedestination"],
            [PyTango.DevBoolean, "result"]],
        'DeleteFile':
            [[PyTango.DevString, "pathtofile"],
            [PyTango.DevBoolean, "result"]],
        'RetrieveFile':
            [[PyTango.DevString, "sourcedestination"],
            [PyTango.DevBoolean, "result"]],
        'ListDir':
            [[PyTango.DevString, "lsdumppath"],
            [PyTango.DevVoid, "none"]],
        }


    #    Attribute definitions
    attr_list = {
        'IsStorageDirEmpty':
            [[PyTango.DevBoolean,
            PyTango.SCALAR,
            PyTango.READ],
            {
                'label': "IsStorageDirectoryEmpty",
                'description': "Checks if the Plexil Storage Directory is empty",
            } ],
        }


def main():
    try:
        py = PyTango.Util(sys.argv)
        py.add_class(PlexilPlanStorageClass,PlexilPlanStorage,'PlexilPlanStorage')

        U = PyTango.Util.instance()
        U.server_init()
        U.server_run()

    except PyTango.DevFailed,e:
        print '-------> Received a DevFailed exception:',e
    except Exception,e:
        print '-------> An unforeseen exception occured....',e

if __name__ == '__main__':
    main()
