# Class describing interception transferred through HI1
#
# Copyright (C) 2011 Matěj Grégr, Michal Kajan, Libor Polčák, Vladimír Veselý
# 
# This program 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.
# 
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

import time
from modules.shared.liexceptions import LIException
from modules.shared.nid import CreateNID

class HI1Intercept(object):

    def __init__(self, liid, nid, level, start, end, itype = "IRI"):
        """ Constructor

        liid Identifier to be used as LIID
        nid Identifier to be used as NID
        level Specifies range of devices that are part of the intercept
          1 - NIDs directly connected to the given NID
          2 - NIDs that are detected to be used on the same interface or by the same computer that
              is using the given NID are also intercepted
          3 - In addition, NIDs that are identified to be used by the same user as is using the
              given NID are also intercepted
        start Start of the interception
        end End of the interception
        itype Type of the interception, if CC present in the string CC data are intercepted

        All arguments are string.

        Allowed formats of time: day.month.year. day.month.year hour:min
        """
        self.__liid = liid
        self.__nid = CreateNID(nid)
        if level not in ["1", "2", "3"]:
            raise LIException("Invalid level %s of interception. Only levels 1 (smallest), 2, 3 are supported"
                    % str(level))
        self.__level = int(level)
        self.__start = self.__parseTime(start)
        self.__end = self.__parseTime(end)
        self.__cc = False
        if self.__end <= self.__start:
            raise LIException("Invalid duration of the exception (from %s to %s)" % (start, end))
        #FIXME configuration of LEMF interfaces

    # Getters
    def getLIID(self):
        return self.__liid

    def getNID(self):
        return self.__nid

    def getLevel(self):
        return self.__level

    def getInterceptionPeriod(self):
        return (self.__start, self.__end)

    def interceptCC(self):
        return self.__cc

    def getINI1AInformation(self):
        """ Returns tuple of configuration used by IRI-IIF """
        return (self.__nid, self.__liid, self.__cc, time.mktime(self.__start), self.__level)

    @staticmethod
    def __parseTime(timeString):
      for fmt in ["%d.%m.%Y", "%d.%m.%Y %H:%M"]:
        try:
            return time.strptime(timeString, fmt)
        except ValueError:
            pass
      try:
          # Actual value of Unix time
          if timeString == "now":
              return time.localtime(time.time())
          # Maximum value of 32-bit signed integer (date: 19-Jan-2038)
          elif timeString == "never":
              return time.localtime(2147483647)
          # Number of seconds since Unix epoch start
          elif timeString.isdigit():
              return time.localtime(int(timeString))
          # 
          else:
              # Value can begin with symbol "+"
              if timeString[:1] == "+":
                  timeString = timeString[1:]
              
              return time.localtime(time.time()+int(timeString))
              # Parse number and string from value
      except:
          raise LIException("Unknown time " + timeString)


    def __repr__(self):
        return "HI1Intercept('%s', %s, '%d', '%d', '%d', '%s')" % ( \
            self.__liid, \
            repr(self.__nid), self.__level, time.mktime(self.__start), \
            time.mktime(self.__end), "CC" if self.__cc else "")

    def __str__(self):
        return repr(self)

    def __eq__(self, other):
        if not isinstance(other, self.__class__):
            return False
        return self.__liid == other.__liid and \
                self.__nid == other.__nid and \
                self.__level == other.__level and \
                self.__start == other.__start and \
                self.__end == other.__end and \
                self.__cc == other.__cc
