package cli

import (
	"fmt"
	"os"
	"strings"
	"time"
)

type FlagStringArray []string

func (array *FlagStringArray) String() string {
	return strings.Join(*array, ", ")
}

func (array *FlagStringArray) Set(s string) error {
	*array = append(*array, s)
	return nil
}

type FileList FlagStringArray

func (fileList FileList) Strings() []string {
	return ([]string)(fileList)
}

func (fileList *FileList) String() string {
	return (*FlagStringArray)(fileList).String()
}

func (fileList *FileList) Set(s string) error {
	if _, err := os.Stat(s); os.IsNotExist(err) {
		return fmt.Errorf("file does not exist: %s", s)
	}
	return (*FlagStringArray)(fileList).Set(s)
}

type Period struct {
	Start time.Time
	Stop  time.Time
}

func (period Period) Empty() bool {
	return period.Stop.Sub(period.Start) == 0
}

func (period *Period) String() string {
	return fmt.Sprintf("%s..%s", period.Start, period.Stop)
}

func (period *Period) Set(s string) error {
	ss := strings.Split(s, "..")
	if err := period.setStartStop(ss[0]); err != nil {
		return err
	}

	if len(ss) != 2 {
	} else if err := period.setStop(ss[1]); err != nil {
		return err
	}

	return nil
}

func (period *Period) setStartStop(s string) error {
	stop, err := period.setT(s, &period.Start)
	period.Stop = stop
	return err
}

func (period *Period) setStop(s string) error {
	_, err := period.setT(s, &period.Stop)
	return err
}

func (*Period) setT(s string, t *time.Time) (time.Time, error) {
	if result, err := time.Parse("2006", s); err == nil {
		*t = result
		return result.AddDate(1, 0, 0).Add(-1 * time.Minute), nil
	}
	if result, err := time.Parse("2006-01", s); err == nil {
		*t = result
		return result.AddDate(0, 1, 0).Add(-1 * time.Minute), nil
	}
	if result, err := time.Parse("2006-01-02", s); err == nil {
		*t = result
		return result.AddDate(0, 0, 1).Add(-1 * time.Minute), nil
	}
	return time.Time{}, fmt.Errorf("unimplemented format: %s", s)
}
