1package cli
2
3import (
4	"time"
5
6	"github.com/dominikbraun/timetrace/core"
7	"github.com/dominikbraun/timetrace/out"
8
9	"github.com/spf13/cobra"
10)
11
12func createCommand(t *core.Timetrace) *cobra.Command {
13	create := &cobra.Command{
14		Use:   "create",
15		Short: "Create a new resource",
16		Run: func(cmd *cobra.Command, args []string) {
17			_ = cmd.Help()
18		},
19	}
20
21	create.AddCommand(createProjectCommand(t))
22	create.AddCommand(createRecordCommand(t))
23
24	return create
25}
26
27func createProjectCommand(t *core.Timetrace) *cobra.Command {
28	createProject := &cobra.Command{
29		Use:   "project <KEY>",
30		Short: "Create a new project",
31		Args:  cobra.ExactArgs(1),
32		Run: func(cmd *cobra.Command, args []string) {
33			key := args[0]
34
35			project := core.Project{
36				Key: key,
37			}
38
39			if err := t.SaveProject(project, false); err != nil {
40				out.Err("Failed to create project: %s", err.Error())
41				return
42			}
43
44			out.Success("Created project %s", key)
45		},
46	}
47
48	return createProject
49}
50
51func createRecordCommand(t *core.Timetrace) *cobra.Command {
52	var options startOptions
53	createRecord := &cobra.Command{
54		Use:   "record <PROJECT KEY> {<YYYY-MM-DD>|today|yesterday} <HH:MM> <HH:MM>",
55		Short: "Create a new record",
56		Args:  cobra.ExactArgs(4),
57		Run: func(cmd *cobra.Command, args []string) {
58			key := args[0]
59			project, err := t.LoadProject(key)
60			if err != nil {
61				out.Err("Failed to get project: %s", key)
62				return
63			}
64
65			date, err := t.Formatter().ParseDate(args[1])
66			if err != nil {
67				out.Err("failed to parse date: %s", err.Error())
68				return
69			}
70
71			start, err := t.Formatter().ParseTime(args[2])
72			if err != nil {
73				out.Err("failed to parse start time: %s", err.Error())
74				return
75			}
76			start = t.Formatter().CombineDateAndTime(date, start)
77
78			end, err := t.Formatter().ParseTime(args[3])
79			if err != nil {
80				out.Err("failed to parse end time: %s", err.Error())
81				return
82			}
83			end = t.Formatter().CombineDateAndTime(date, end)
84
85			if end.Before(start) {
86				out.Err("end time is before start time!")
87				return
88			}
89
90			now := time.Now()
91			if now.Before(start) || now.Before(end) {
92				out.Err("provided record happens in the future!")
93				return
94			}
95
96			record := core.Record{
97				Project:    project,
98				Start:      start,
99				End:        &end,
100				IsBillable: options.isBillable,
101			}
102
103			collides, err := t.RecordCollides(record)
104			if err != nil {
105				out.Err("Error on check if record collides: %s", err.Error())
106				return
107			}
108			if collides {
109				return
110			}
111
112			if err := t.SaveRecord(record, false); err != nil {
113				out.Err("Failed to create record: %s", err.Error())
114				return
115			}
116
117			out.Success("Created record %s in project %s", t.Formatter().TimeString(record.Start), key)
118		},
119	}
120
121	createRecord.Flags().BoolVarP(&options.isBillable, "billable", "b",
122		false, `mark tracked time as billable`)
123
124	return createRecord
125}
126