package audit

import (
	"errors"
	"time"
)

type Source string
type EventType string
type PolicyDecision string

const (
	SourceControlPlane Source = "control_plane"
	SourceEdge         Source = "edge"
	SourceNode         Source = "node"

	DecisionAllow PolicyDecision = "allow"
	DecisionDeny  PolicyDecision = "deny"
	DecisionWarn  PolicyDecision = "warn"

	DefaultEdgeLocalRetentionDays             = 30
	DefaultControlPlaneMetadataRetentionDays  = 90
	MetadataRedactionMarker                  = "redaction_marker"
	MetadataCredentialReference              = "credential_ref"
)

const (
	TypeExecutionRequested       EventType = "execution.requested"
	TypeExecutionPolicyEvaluated EventType = "execution.policy_evaluated"
	TypeExecutionDispatched      EventType = "execution.dispatched"
	TypeExecutionStarted         EventType = "execution.started"
	TypeExecutionCompleted       EventType = "execution.completed"
	TypeExecutionFailed          EventType = "execution.failed"
	TypeExecutionCanceled        EventType = "execution.canceled"

	TypeTerminalSessionRequested EventType = "terminal.session_requested"
	TypeTerminalSessionStarted   EventType = "terminal.session_started"
	TypeTerminalCommandSubmitted EventType = "terminal.command_submitted"
	TypeTerminalCommandCompleted EventType = "terminal.command_completed"
	TypeTerminalSessionClosed    EventType = "terminal.session_closed"

	TypeBootstrapEnrollmentRequested EventType = "bootstrap.enrollment_requested"
	TypeBootstrapCredentialIssued    EventType = "bootstrap.credential_issued"
	TypeBootstrapNodeRegistered      EventType = "bootstrap.node_registered"
	TypeBootstrapEnrollmentFailed    EventType = "bootstrap.enrollment_failed"
	TypeBootstrapRevoked             EventType = "bootstrap.revoked"
)

type Event struct {
	EventID        string
	Type           EventType
	Source         Source
	ActorID        string
	RequestID      string
	RunID          string
	SessionID      string
	EdgeID         string
	NodeID         string
	Adapter        string
	Target         string
	CredentialRef  string
	PolicyDecision PolicyDecision
	PolicyRule     string
	Timestamp      time.Time
	Status         string
	Error          string
	Metadata       map[string]string
}

func (e Event) Validate() error {
	if e.Type == "" {
		return errors.New("audit event type is required")
	}
	if e.Source == "" {
		return errors.New("audit event source is required")
	}
	if e.Timestamp.IsZero() {
		return errors.New("audit event timestamp is required")
	}
	return nil
}

func (e Event) CopyMetadata() map[string]string {
	if e.Metadata == nil {
		return nil
	}
	out := make(map[string]string, len(e.Metadata))
	for k, v := range e.Metadata {
		out[k] = v
	}
	return out
}
