from FreeTAKServer.model.FTSModel.fts_protocol_object import FTSProtocolObject
import datetime as dt
from FreeTAKServer.model.FTSModel.Detail import Detail
from .Point import Point
from FreeTAKServer.model.FTSModelVariables.EventVariables import EventVariables as vars
import uuid

class Event(FTSProtocolObject):
    # TODO: fix emergency methods
    # Event.py
    # Python implementation of the Class Event
    # represents a TAK event: this class is instantiated with a standard set of
    #    values.
    # Generated by Enterprise Architect
    # Created on: 11-Feb-2020 11:08:07 AM
    # Original author: Corvo
    #

    # event as an XML
    #<?xml version="1.0" encoding="UTF-8" standalone="yes"?><event version="2.0" uid="Linux-ABC.server-ping" type="b-t-f" time="2020-02-14T20:32:31.444Z" start="2020-02-14T20:32:31.444Z" stale="2020-02-15T20:32:31.444Z" how="h-g-i-g-o"> 
        
        #default constructor

    def __init__(self):
        
        
        self.version = None
        self.uid = None
        self.type = None
        self.how = None

        self.detail = None
        self.point = None
        self.start = None
        case = {

            'default': self.defaultFunc,

            'timeout': self.timeoutFunc
            
            }


        # flag to determin e if this event is a geo chcat if so, will be added as a
        # prefix to the uid
        
        # starting time when an event should be considered valid
        start = "%Y-%m-%dT%H:%M:%SZ"
        # basic event
        # Gives a hint about how the coordinates were generated
        

        # Schema version of this event instance (e.g.  2.0)
            
        # time stamp: when the event was generated
        time = "%Y-%m-%dT%H:%M:%SZ" 
        
        # Hierarchically organized hint about event type (defaultis is 'a-f-G-I'
        # for infrastructure)
        
            # ending time when an event should no longer be considered valid
        stale = "%Y-%m-%dT%H:%M:%SZ" 
        
            # Globally unique name for this information on this event can have
            # additional information attached.
        # e.g.  -ping means that this request is a ping
        
        # flag to determine if this event is a Ping, in this case append to the UID
        
    @staticmethod
    def Connection(version=vars.connection().VERSIONNUM, uid=vars.connection().UID, type=vars.connection().TYPE,
                  how=vars.connection().HOW, time=vars.connection().TIME, start=vars.connection().START,
                  stale=vars.connection().STALE):
        event = Event()
        event.setdetail(Detail.Connection())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def GeoChat(version=vars.geochat().VERSIONNUM, uid=vars.geochat().UID, type=vars.geochat().TYPE,
                how=vars.geochat().HOW, time=vars.geochat().TIME, start=vars.geochat().START,
                stale=vars.geochat().STALE):
        event = Event()
        event.setdetail(Detail.GeoChat())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def Ping(version=vars.ping().VERSIONNUM, uid=vars.ping().UID, type=vars.ping().TYPE,
             how=vars.ping().HOW, time=vars.ping().TIME, start=vars.ping().START,
             stale=vars.ping().STALE):
        event = Event()
        event.setdetail(Detail.Ping())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def Other(version=vars.other().VERSIONNUM, uid=vars.other().UID, type=vars.other().TYPE,
              how=vars.other().HOW, time=vars.other().TIME, start=vars.other().START,
              stale=vars.other().STALE):
        event = Event()
        event.setdetail(Detail.Other())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event
               
    @staticmethod
    # this is the only constructor which doesn't instantiate detail as detail is a required protobuf
    # attribute and will therefore be in the message regardless
    def FederatedCoT(version=vars.FederatedCoT().VERSIONNUM, uid=vars.FederatedCoT().UID, type=vars.FederatedCoT().TYPE,
              how=vars.FederatedCoT().HOW, time=vars.FederatedCoT().TIME, start=vars.FederatedCoT().START,
              stale=vars.FederatedCoT().STALE):
        event = Event()
        event.setpoint(Point())
        event.setdetail(Detail.FederatedCoT())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def emergecyOn(version=vars.emergency_on().VERSIONNUM, uid=vars.emergency_on().UID, type=vars.emergency_on().TYPE,
                   how=vars.emergency_on().HOW, time=vars.emergency_on().TIME, start=vars.emergency_on().START,
                   stale=vars.emergency_on().STALE):
        event = Event()
        event.setdetail(Detail.emergencyOn())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def emergecyOff(version=vars.emergency_off().VERSIONNUM, uid=vars.emergency_off().UID, type=vars.emergency_off().TYPE,
                    how=vars.emergency_off().HOW, time=vars.emergency_off().TIME, start=vars.emergency_off().START,
                    stale=vars.emergency_off().STALE):
        event = Event()
        event.setdetail(Detail.emergencyOff())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def dropPoint(version=vars.drop_point().VERSIONNUM, uid=vars.drop_point().UID, type=vars.drop_point().TYPE,
                  how=vars.drop_point().HOW, time=vars.drop_point().TIME, start=vars.drop_point().START,
                  stale=vars.drop_point().STALE):
        event = Event()
        event.setdetail(Detail.dropPoint())
        event.setpoint(Point())
        event.setversion(version)
        event.setuid(uid)
        event.settype(type)
        event.sethow(how)
        event.settime(time)
        event.setstart(start)
        event.setstale(stale)
        return event

    @staticmethod
    def disconnect(UID=vars.disconnect().uid, VERSION=vars.disconnect().version, TYPE=vars.disconnect().type,
                   TIME=vars.disconnect().time, START=vars.disconnect().start, STALE=vars.disconnect().stale,
                   HOW=vars.disconnect().how):
        event = Event()
        event.setuid(UID)
        event.setversion(VERSION)
        event.settype(TYPE)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.sethow(HOW)
        event.point = Point()
        event.detail = Detail.disconnect()
        return event

    @staticmethod
    def takPong(VERSION=vars.takPong().version, UID=vars.takPong().uid, TYPE=vars.takPong().type,
                HOW=vars.takPong().how, TIME=vars.takPong().time, START=vars.takPong().start,
                STALE=vars.takPong().stale):
        event = Event()
        event.setversion(VERSION)
        event.setuid(UID)
        event.settype(TYPE)
        event.sethow(HOW)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.point = Point()
        return event

    @staticmethod
    def UserUpdate(VERSION=vars.UserUpdate().version, UID=vars.UserUpdate().uid, TYPE=vars.UserUpdate().type,
                   HOW=vars.UserUpdate().how, TIME=vars.UserUpdate().time, START=vars.UserUpdate().start,
                   STALE=vars.UserUpdate().stale):
        event = Event()
        event.setversion(VERSION)
        event.setuid(UID)
        event.settype(TYPE)
        event.sethow(HOW)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.point = Point()
        event.detail = Detail.UserUpdate()
        return event

    @staticmethod
    def SimpleCoT(VERSION=vars.SimpleCoT().version, UID=vars.SimpleCoT().uid, TYPE=vars.SimpleCoT().type,
                  TIME=vars.SimpleCoT().time, START=vars.SimpleCoT().start, STALE=vars.SimpleCoT().stale,
                  HOW=vars.SimpleCoT().how):
        event = Event()
        event.setversion(VERSION)
        event.setuid(UID)
        event.settype(TYPE)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.sethow(HOW)
        event.detail = Detail.SimpleCoT()
        event.point = Point()
        return event

    @staticmethod
    def Presence(VERSION=vars.Presence().version, UID=vars.Presence().uid, TYPE=vars.Presence().type,
                  TIME=vars.Presence().time, START=vars.Presence().start, STALE=vars.Presence().stale,
                  HOW=vars.Presence().how):
        event = Event()
        event.setversion(VERSION)
        event.setuid(UID)
        event.settype(TYPE)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.sethow(HOW)
        event.detail = Detail.Presence()
        event.point = Point()
        return event

    @staticmethod
    def ExcheckUpdate(VERSION=vars.ExcheckUpdate().version, UID=vars.ExcheckUpdate().uid,
                              TYPE=vars.ExcheckUpdate().type, TIME=vars.ExcheckUpdate().time,
                              START=vars.ExcheckUpdate().start, STALE=vars.ExcheckUpdate().stale,
                              HOW=vars.ExcheckUpdate().how):
        event = Event()
        event.setversion(VERSION)
        event.setuid(UID)
        event.settype(TYPE)
        event.settime(TIME)
        event.setstart(START)
        event.setstale(STALE)
        event.sethow(HOW)
        event.point = Point()
        event.detail = Detail.ExcheckUpdate()
        return event

    def defaultFunc(self, DATETIME_FMT,  version, uid, type, how, isGeochat, isPing):
        self.how = how

        timer = dt.datetime
        now = timer.utcnow()
        zulu = now.strftime(DATETIME_FMT)
        stale_part = dt.datetime.strptime(zulu, DATETIME_FMT) + dt.timedelta(minutes = 2)
        stale_part = stale_part.strftime(DATETIME_FMT)
        self.setstale(str(stale_part))
        self.setstart(zulu)
        self.settime(zulu)
        self.type = type
        self.setuid(isGeochat=isGeochat, isPing=isPing)
        self.version = version

    def timeoutFunc(self, DATETIME_FMT, version, uid, type, how, isGeochat, isPing):
        self.how = how

        timer = dt.datetime
        now = timer.utcnow()
        zulu = now.strftime(DATETIME_FMT)
        stale_part = dt.datetime.strptime(zulu, DATETIME_FMT) + dt.timedelta(minutes = 2)
        stale_part = stale_part.strftime(DATETIME_FMT)
        self.setstale(str(stale_part))
        self.setstart(zulu)
        self.settime(zulu)
        self.type = type
        self.setuid(isGeochat=isGeochat, isPing=isPing)
        self.version = version
        #start getter

    def getstart(self): 
        return self.start 
    
        # start setter
    def setstart(self, start=0):
        DATETIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ"
        if start == None:
            timer = dt.datetime
            now = timer.utcnow()
            zulu = now.strftime(DATETIME_FMT)
            self.start = zulu
        else:
            self.start = start

    
        # how getter
    def gethow(self): 
        return self.how 
    
        
    # how setter
    def sethow(self, how=0):  
        self.how = how 

        # uid getter
    def getuid(self): 
        return self.uid 
    
        # uid setter
    def setuid(self, uid):
        if uid == None:
            self.uid = str(uuid.uuid1())

        else:
            self.uid = uid

            # version getter
    def getversion(self): 
        return self.version 
    
        # version setter
    def setversion(self, version):  
        self.version = version 

            # time getter
    def gettime(self): 
        return self.time 
    
        # time setter
    def settime(self, time=0):
        DATETIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ"
        if time == None:
            timer = dt.datetime
            now = timer.utcnow()
            zulu = now.strftime(DATETIME_FMT)
            self.time = zulu
        else:
            self.time = time
        
        # stale getter
    def getstale(self): 
        return self.stale 
    
        # stale setter
    def setstale(self, stale = None,staletime=60):
        if stale == None:
            DATETIME_FMT = "%Y-%m-%dT%H:%M:%S.%fZ"
            timer = dt.datetime
            now = timer.utcnow()
            zulu = now.strftime(DATETIME_FMT)
            add = dt.timedelta(seconds=staletime)
            stale_part = dt.datetime.strptime(zulu, DATETIME_FMT) + add
            self.stale = stale_part.strftime(DATETIME_FMT)
        else:
            self.stale = stale

            # type getter
    def gettype(self): 
        return self.type 
    
        # type setter
    def settype(self, type=0):  
        self.type = type

    def getpoint(self):
        return self.point

        # type setter

    def setpoint(self, Point=None):
        self.point = Point

    def getdetail(self):
        return self.detail

        # type setter

    def setdetail(self, detail=None):
        self.detail = detail
if __name__ == "__main__":
    Event()

