1package cli
2
3import (
4	"encoding/json"
5	"errors"
6	"fmt"
7	"strings"
8
9	"github.com/dominikbraun/timetrace/core"
10	"github.com/dominikbraun/timetrace/out"
11
12	"github.com/spf13/cobra"
13)
14
15type statusReport struct {
16	Project            string `json:"project"`
17	TrackedTimeCurrent string `json:"trackedTimeCurrent"`
18	TrackedTimeToday   string `json:"trackedTimeToday"`
19	BreakTimeToday     string `json:"breakTimeToday"`
20}
21
22type statusOptions struct {
23	format string
24	output string
25}
26
27func statusCommand(t *core.Timetrace) *cobra.Command {
28	var options statusOptions
29
30	status := &cobra.Command{
31		Use:   "status",
32		Short: "Display the current tracking status",
33		Run: func(cmd *cobra.Command, args []string) {
34			report, err := t.Status()
35			if errors.Is(err, core.ErrTrackingNotStarted) {
36				out.Info("You haven't started tracking time today")
37				return
38			} else if err != nil {
39				out.Err("Failed to obtain status: %s", err.Error())
40				return
41			}
42
43			if report == nil {
44				out.Info("You're not tracking time at the moment")
45				return
46			}
47
48			statusReport := statusReport{
49				Project:            defaultString,
50				TrackedTimeCurrent: defaultString,
51				TrackedTimeToday:   t.Formatter().FormatDuration(report.TrackedTimeToday),
52				BreakTimeToday:     t.Formatter().FormatDuration(report.BreakTimeToday),
53			}
54
55			if report.Current != nil {
56				statusReport.Project = report.Current.Project.Key
57			}
58
59			if report.TrackedTimeCurrent != nil {
60				statusReport.TrackedTimeCurrent = t.Formatter().FormatDuration(*report.TrackedTimeCurrent)
61			}
62
63			if options.format != "" {
64				format := options.format
65				format = strings.ReplaceAll(format, "{project}", statusReport.Project)
66				format = strings.ReplaceAll(format, "{trackedTimeCurrent}", statusReport.TrackedTimeCurrent)
67				format = strings.ReplaceAll(format, "{trackedTimeToday}", statusReport.BreakTimeToday)
68				format = strings.ReplaceAll(format, "{breakTimeToday}", statusReport.BreakTimeToday)
69				format = strings.ReplaceAll(format, `\n`, "\n")
70				fmt.Printf(format)
71				return
72			}
73
74			if options.output != "" {
75				switch options.output {
76				case "json":
77					bytes, err := json.MarshalIndent(statusReport, "", "\t")
78					if err != nil {
79						out.Err("error printing JSON: %s", err.Error())
80						return
81					}
82					fmt.Println(string(bytes))
83					return
84				default:
85					out.Err("unknown output format: %s", options.format)
86					return
87				}
88			}
89
90			rows := [][]string{
91				{
92					statusReport.Project,
93					statusReport.TrackedTimeCurrent,
94					statusReport.TrackedTimeToday,
95					statusReport.BreakTimeToday,
96				},
97			}
98
99			out.Table([]string{"Current project", "Worked since start", "Worked today", "Breaks"}, rows, nil)
100		},
101	}
102
103	status.Flags().StringVarP(&options.format, "format", "f", "", "Format string, availiable:\n{project}, {trackedTimeCurrent}, {trackedTimeToday}, {breakTimeToday}")
104	status.Flags().StringVarP(&options.output, "output", "o", "", "The output format. Available: json")
105
106	return status
107}
108