package events

import (
	"encoding/json"
	"time"
)

const athenaTimeFormat = "2006-01-02 15:04:05.000 MST"

// Time is the json marshallable time.Time for athena-compatible time format
type Time time.Time

// MarshalJSON implements json.Marshaller
func (t Time) MarshalJSON() ([]byte, error) {
	return json.Marshal(time.Time(t).UTC().Format(athenaTimeFormat))
}

// UnmarshalJSON implements json.Unmarshaller
func (t *Time) UnmarshalJSON(data []byte) (err error) {
	var asStr string
	if err = json.Unmarshal(data, &asStr); err != nil {
		return err
	}

	if asStr == "" {
		*t = Time{}
		return nil
	}

	rawTime, err := time.ParseInLocation(athenaTimeFormat, asStr, time.UTC)
	if err != nil {
		return err
	}

	*t = Time(rawTime.UTC())
	return nil
}

// Event is the base to all events
type Event struct {
	Name            string `json:"event"`
	Category        string `json:"category"`
	IPAddress       string `json:"ip_address"`
	ServiceName     string `json:"service_name"`
	ServiceID       string `json:"service_id"`
	HostName        string `json:"hostname"`
	LDAPUser        string `json:"ldap_user"`
	AWSPrincipal    string `json:"aws_principal"`
	CallerID        string `json:"caller_id"`
	CallerName      string `json:"caller_name"`
	CalleeID        string `json:"callee_id"`
	CalleeName      string `json:"callee_name"`
	StatusCode      string `json:"status_code"`
	URLPath         string `json:"url_path"`
	PassthroughMode string `json:"passthrough_mode"`
	Message         string `json:"message"`
	// 2006-01-02 03:04:05.000 MST
	Timestamp Time `json:"time"`
}

// FillDefaults will fill the defaults of another event
func (e *Event) FillDefaults(other interface{}) {

	switch otherEvent := other.(type) {
	case *Event:
		e.fillDefaults(otherEvent)
	}
}

func (e *Event) fillDefaults(otherEvent *Event) {
	if otherEvent == nil {
		return
	}

	if otherEvent.Name == "" {
		otherEvent.Name = e.Name
	}
	if otherEvent.Category == "" {
		otherEvent.Category = e.Category
	}
	if otherEvent.IPAddress == "" {
		otherEvent.IPAddress = e.IPAddress
	}
	if otherEvent.ServiceName == "" {
		otherEvent.ServiceName = e.ServiceName
	}
	if otherEvent.ServiceID == "" {
		otherEvent.ServiceID = e.ServiceID
	}
	if otherEvent.HostName == "" {
		otherEvent.HostName = e.HostName
	}
	if otherEvent.LDAPUser == "" {
		otherEvent.LDAPUser = e.LDAPUser
	}
	if otherEvent.AWSPrincipal == "" {
		otherEvent.AWSPrincipal = e.AWSPrincipal
	}
	if otherEvent.CallerID == "" {
		otherEvent.CallerID = e.CallerID
	}
	if otherEvent.CallerName == "" {
		otherEvent.CallerName = e.CallerName
	}
	if otherEvent.CalleeID == "" {
		otherEvent.CalleeID = e.CalleeID
	}
	if otherEvent.CalleeName == "" {
		otherEvent.CalleeName = e.CalleeName
	}
	if otherEvent.StatusCode == "" {
		otherEvent.StatusCode = e.StatusCode
	}
	if otherEvent.URLPath == "" {
		otherEvent.URLPath = e.URLPath
	}
	if otherEvent.PassthroughMode == "" {
		otherEvent.PassthroughMode = e.PassthroughMode
	}
	if otherEvent.Message == "" {
		otherEvent.Message = e.Message
	}
	if time.Time(otherEvent.Timestamp).IsZero() {
		otherEvent.Timestamp = e.Timestamp
	}
}
