From 15dbb12758a2a435f684fafec12ef2866c36565a Mon Sep 17 00:00:00 2001
From: Andrej Rasevic <andrej@rasevicengineering.com>
Date: Fri, 14 Jan 2022 00:11:25 -0500
Subject: [PATCH] adding exercise 2

---
 exercises/exercise2/Exercise2_Description.md | 16 ++++
 exercises/exercise2/cmd/todo/main.go         | 86 ++++++++++++++++++
 exercises/exercise2/go.mod                   |  3 +
 exercises/exercise2/todo.go                  | 92 ++++++++++++++++++++
 4 files changed, 197 insertions(+)
 create mode 100644 exercises/exercise2/Exercise2_Description.md
 create mode 100644 exercises/exercise2/cmd/todo/main.go
 create mode 100644 exercises/exercise2/go.mod
 create mode 100644 exercises/exercise2/todo.go

diff --git a/exercises/exercise2/Exercise2_Description.md b/exercises/exercise2/Exercise2_Description.md
new file mode 100644
index 0000000..8d426c6
--- /dev/null
+++ b/exercises/exercise2/Exercise2_Description.md
@@ -0,0 +1,16 @@
+# Exercise 2: 
+
+## Due Date: Sunday, January 16, 2022 11:59 PM
+## Objectives: To get familiar with using fundamentals of Go idioms and data structures.
+
+## Specifications/Requirements
+1. You are given a go module: __exercise2__. The interface for your command line interface application has been provided for you. It is inside of the __cmd/todo__ directory. You need to complete the TODO items inside of __todo.go__. They consist of the following:  
+*   complete the definition of the type item struct  
+*   complete the Add method which adds a new todo item to the list
+*   complete the Complete method which updates the given todo item as completed
+*   complete the Delete method which removes the given todo item from the list 
+
+
+To deliver your submission you will need to commit your changes locally and push to your repo on the university gitlab server.  
+__NOTE__: You should not commit any executables or binaries as a result of compiling and building your application. 
+
diff --git a/exercises/exercise2/cmd/todo/main.go b/exercises/exercise2/cmd/todo/main.go
new file mode 100644
index 0000000..190fba7
--- /dev/null
+++ b/exercises/exercise2/cmd/todo/main.go
@@ -0,0 +1,86 @@
+package main
+
+import (
+  "flag"
+  "fmt"
+  "os"
+
+  "gitlab.cs.umd.edu/arasevic/cmsc398Bwinter2022-student/exercises/exercise2"
+)
+
+// Default file name
+var todoFileName = "todo.json"
+
+func main() {
+  // Parsing command line flags
+  task := flag.String("task", "", "Task to be added to the ToDo list")
+  list := flag.Bool("list", false, "List all tasks")
+  complete := flag.Int("complete", 0, "Item to be completed")
+	delete := flag.Int("delete", -1, "Item to be deleted")
+
+  flag.Usage = func() {
+    fmt.Fprintf(flag.CommandLine.Output(),
+      "%s cli client. CMSC398B Winter 2022 Exercise 2\n", os.Args[0])
+    fmt.Fprintln(flag.CommandLine.Output(), "Usage information:")
+    flag.PrintDefaults()
+  }
+
+  flag.Parse()
+
+  // Check if the user defined the ENV VAR for a custom file name
+  if os.Getenv("TODO_FILENAME") != "" {
+    todoFileName = os.Getenv("TODO_FILENAME")
+  }
+
+  // Define an items list
+  l := &todo.List{}
+
+  // Use the Get command to read to do items from file
+  if err := l.Get(todoFileName); err != nil {
+    fmt.Fprintln(os.Stderr, err)
+    os.Exit(1)
+  }
+
+  // Decide what to do based on the provided flags
+  switch {
+  case *list:
+    // List current to do items
+    fmt.Print(l)
+  case *complete > 0:
+    // Complete the given item
+    if err := l.Complete(*complete); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+
+    // Save the new list
+    if err := l.Save(todoFileName); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+  case *task != "":
+    // Add the task
+    l.Add(*task)
+
+    // Save the new list
+    if err := l.Save(todoFileName); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }
+	case *delete >= 0:
+		// Delete the given todo
+		if err := l.Delete(*delete); err != nil {
+      fmt.Fprintln(os.Stderr, err)
+      os.Exit(1)
+    }	
+		// Save the new list
+		if err := l.Save(todoFileName); err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+    }
+  default:
+    // Invalid flag provided
+    flag.Usage()
+    os.Exit(1)
+  }
+}
diff --git a/exercises/exercise2/go.mod b/exercises/exercise2/go.mod
new file mode 100644
index 0000000..9dd05a9
--- /dev/null
+++ b/exercises/exercise2/go.mod
@@ -0,0 +1,3 @@
+module gitlab.cs.umd.edu/arasevic/cmsc398Bwinter2022-student/exercises/exercise2
+
+go 1.17
diff --git a/exercises/exercise2/todo.go b/exercises/exercise2/todo.go
new file mode 100644
index 0000000..8a05cf4
--- /dev/null
+++ b/exercises/exercise2/todo.go
@@ -0,0 +1,92 @@
+package todo
+
+import (
+  "encoding/json"
+  "errors"
+  "fmt"
+  "io/ioutil"
+  "os"
+  "time"
+)
+
+//TODO
+// item struct represents a ToDo item
+// Members: Task (string) Done (bool) CreateAt (time.Time) CompletedAt (time.Time)
+type item struct {
+  
+}
+
+// List represents a list of ToDo items
+type List []item
+
+//String prints out a formatted list
+//Implements the fmt.Stringer interface
+func (l *List) String() string {
+  formatted := ""
+
+  for k, t := range *l {
+    prefix := "  "
+    if t.Done {
+      prefix = "X "
+    }
+
+    // Adjust the item number k to print numbers starting from 1 instead of 0
+    formatted += fmt.Sprintf("%s%d: %s\n", prefix, k+1, t.Task)
+  }
+
+  return formatted
+}
+
+// TODO
+// Add creates a new todo item and appends it to the list
+func (l *List) Add(task string) {
+ 
+}
+
+//TODO
+// Complete method marks a ToDo item as completed by
+// setting Done = true and CompletedAt to the current time
+func (l *List) Complete(i int) error {
+  
+  //if i <= 0 || i > len(ls) {
+    //return fmt.Errorf("Item %d does not exist", i)
+  //}
+
+  return nil
+}
+
+//TODO
+// Delete method deletes a ToDo item from the list
+func (l *List) Delete(i int) error {
+  
+  return nil
+}
+
+// Save method encodes the List as JSON and saves it
+// using the provided file name
+func (l *List) Save(filename string) error {
+  data, err := json.Marshal(l)
+  if err != nil {
+    return err
+  }
+
+  return ioutil.WriteFile(filename, data, 0644)
+}
+
+// Get method opens the provided file name, decodes
+// the JSON data and parse into a List
+func (l *List) Get(filename string) error {
+  file, err := ioutil.ReadFile(filename)
+  if err != nil {
+    if errors.Is(err, os.ErrNotExist) {
+      return nil
+    }
+    return err
+  }
+
+  if len(file) == 0 {
+    return nil
+  }
+
+  return json.Unmarshal(file, l)
+}
-- 
GitLab