package rfctime

import "time"

type RFCTime interface {
	AnyTime

	Time() time.Time
	Serialize() string

	After(u AnyTime) bool
	Before(u AnyTime) bool
	Equal(u AnyTime) bool

	Sub(u AnyTime) time.Duration
}

type AnyTime interface {
	MarshalJSON() ([]byte, error)

	MarshalBinary() ([]byte, error)

	GobEncode() ([]byte, error)

	MarshalText() ([]byte, error)

	IsZero() bool
	Date() (year int, month time.Month, day int)
	Year() int
	Month() time.Month
	Day() int
	Weekday() time.Weekday
	ISOWeek() (year, week int)
	Clock() (hour, min, sec int)
	Hour() int
	Minute() int
	Second() int
	Nanosecond() int
	YearDay() int
	Unix() int64
	UnixMilli() int64
	UnixMicro() int64
	UnixNano() int64
	Format(layout string) string
	GoString() string
	String() string

	Location() *time.Location
}

type RFCDuration interface {
	Time() time.Time
	Serialize() string

	UnmarshalJSON(bytes []byte) error
	MarshalJSON() ([]byte, error)

	MarshalBinary() ([]byte, error)
	UnmarshalBinary(data []byte) error

	GobEncode() ([]byte, error)
	GobDecode(data []byte) error

	MarshalText() ([]byte, error)
	UnmarshalText(data []byte) error

	After(u AnyTime) bool
	Before(u AnyTime) bool
	Equal(u AnyTime) bool
	IsZero() bool
	Date() (year int, month time.Month, day int)
	Year() int
	Month() time.Month
	Day() int
	Weekday() time.Weekday
	ISOWeek() (year, week int)
	Clock() (hour, min, sec int)
	Hour() int
	Minute() int
	Second() int
	Nanosecond() int
	YearDay() int
	Sub(u AnyTime) time.Duration
	Unix() int64
	UnixMilli() int64
	UnixMicro() int64
	UnixNano() int64
	Format(layout string) string
	GoString() string
	String() string
}

func tt(v AnyTime) time.Time {
	if r, ok := v.(time.Time); ok {
		return r
	}
	if r, ok := v.(RFCTime); ok {
		return r.Time()
	}
	return time.Unix(0, v.UnixNano()).In(v.Location())
}