main
1package manifest
2
3import (
4 "encoding/json"
5 "fmt"
6 "os"
7 "sort"
8 "time"
9)
10
11// NewClipIndex creates a new ClipIndex.
12func NewClipIndex(cameraID, cameraName, date string) *ClipIndex {
13 now := time.Now()
14 return &ClipIndex{
15 CameraID: cameraID,
16 CameraName: cameraName,
17 Date: date,
18 CreatedAt: now,
19 UpdatedAt: now,
20 Clips: make([]*ClipEntry, 0),
21 }
22}
23
24// AddClip adds a clip entry to the index.
25func (ci *ClipIndex) AddClip(entry *ClipEntry) {
26 ci.Clips = append(ci.Clips, entry)
27 ci.UpdatedAt = time.Now()
28}
29
30// Sort orders clips by (start_ms, end_ms, event_id) for deterministic ordering.
31func (ci *ClipIndex) Sort() {
32 sort.Slice(ci.Clips, func(i, j int) bool {
33 a, b := ci.Clips[i], ci.Clips[j]
34 if a.StartMs != b.StartMs {
35 return a.StartMs < b.StartMs
36 }
37 if a.EndMs != b.EndMs {
38 return a.EndMs < b.EndMs
39 }
40 return a.EventID < b.EventID
41 })
42}
43
44// FindByEventID returns the clip entry with the given event ID, or nil.
45func (ci *ClipIndex) FindByEventID(eventID string) *ClipEntry {
46 for _, c := range ci.Clips {
47 if c.EventID == eventID {
48 return c
49 }
50 }
51 return nil
52}
53
54// Write saves the clip index to a JSON file.
55func (ci *ClipIndex) Write(path string) error {
56 ci.UpdatedAt = time.Now()
57 ci.Sort()
58
59 data, err := json.MarshalIndent(ci, "", " ")
60 if err != nil {
61 return fmt.Errorf("marshaling clip index: %w", err)
62 }
63
64 err = os.WriteFile(path, data, 0644)
65 if err != nil {
66 return fmt.Errorf("writing clip index: %w", err)
67 }
68
69 return nil
70}
71
72// ReadClipIndex loads a clip index from a JSON file.
73func ReadClipIndex(path string) (*ClipIndex, error) {
74 data, err := os.ReadFile(path)
75 if err != nil {
76 return nil, fmt.Errorf("reading clip index: %w", err)
77 }
78
79 var ci ClipIndex
80 err = json.Unmarshal(data, &ci)
81 if err != nil {
82 return nil, fmt.Errorf("parsing clip index: %w", err)
83 }
84
85 return &ci, nil
86}
87
88// WriteDayMetadata saves day metadata to a JSON file.
89func WriteDayMetadata(path string, meta *DayMetadata) error {
90 data, err := json.MarshalIndent(meta, "", " ")
91 if err != nil {
92 return fmt.Errorf("marshaling day metadata: %w", err)
93 }
94
95 err = os.WriteFile(path, data, 0644)
96 if err != nil {
97 return fmt.Errorf("writing day metadata: %w", err)
98 }
99
100 return nil
101}