package rfctime

import (
	"encoding/json"
	"strconv"
	"time"
)

type UnixMilliTime time.Time

func (t UnixMilliTime) Time() time.Time {
	return time.Time(t)
}

func (t UnixMilliTime) MarshalBinary() ([]byte, error) {
	return (time.Time)(t).MarshalBinary()
}

func (t *UnixMilliTime) UnmarshalBinary(data []byte) error {
	return (*time.Time)(t).UnmarshalBinary(data)
}

func (t UnixMilliTime) GobEncode() ([]byte, error) {
	return (time.Time)(t).GobEncode()
}

func (t *UnixMilliTime) GobDecode(data []byte) error {
	return (*time.Time)(t).GobDecode(data)
}

func (t *UnixMilliTime) UnmarshalJSON(data []byte) error {
	str := ""
	if err := json.Unmarshal(data, &str); err != nil {
		return err
	}
	t0, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		return err
	}
	*t = UnixMilliTime(time.UnixMilli(t0))
	return nil
}

func (t UnixMilliTime) MarshalJSON() ([]byte, error) {
	str := strconv.FormatInt(t.Time().UnixMilli(), 10)
	return json.Marshal(str)
}

func (t UnixMilliTime) MarshalText() ([]byte, error) {
	return []byte(strconv.FormatInt(t.Time().UnixMilli(), 10)), nil
}

func (t *UnixMilliTime) UnmarshalText(data []byte) error {
	t0, err := strconv.ParseInt(string(data), 10, 64)
	if err != nil {
		return err
	}
	*t = UnixMilliTime(time.UnixMilli(t0))
	return nil
}

func (t UnixMilliTime) Serialize() string {
	return strconv.FormatInt(t.Time().UnixMilli(), 10)
}

func (t UnixMilliTime) After(u AnyTime) bool {
	return t.Time().After(tt(u))
}

func (t UnixMilliTime) Before(u AnyTime) bool {
	return t.Time().Before(tt(u))
}

func (t UnixMilliTime) Equal(u AnyTime) bool {
	return t.Time().Equal(tt(u))
}

func (t UnixMilliTime) IsZero() bool {
	return t.Time().IsZero()
}

func (t UnixMilliTime) Date() (year int, month time.Month, day int) {
	return t.Time().Date()
}

func (t UnixMilliTime) Year() int {
	return t.Time().Year()
}

func (t UnixMilliTime) Month() time.Month {
	return t.Time().Month()
}

func (t UnixMilliTime) Day() int {
	return t.Time().Day()
}

func (t UnixMilliTime) Weekday() time.Weekday {
	return t.Time().Weekday()
}

func (t UnixMilliTime) ISOWeek() (year, week int) {
	return t.Time().ISOWeek()
}

func (t UnixMilliTime) Clock() (hour, min, sec int) {
	return t.Time().Clock()
}

func (t UnixMilliTime) Hour() int {
	return t.Time().Hour()
}

func (t UnixMilliTime) Minute() int {
	return t.Time().Minute()
}

func (t UnixMilliTime) Second() int {
	return t.Time().Second()
}

func (t UnixMilliTime) Nanosecond() int {
	return t.Time().Nanosecond()
}

func (t UnixMilliTime) YearDay() int {
	return t.Time().YearDay()
}

func (t UnixMilliTime) Add(d time.Duration) UnixMilliTime {
	return UnixMilliTime(t.Time().Add(d))
}

func (t UnixMilliTime) Sub(u AnyTime) time.Duration {
	return t.Time().Sub(tt(u))
}

func (t UnixMilliTime) AddDate(years int, months int, days int) UnixMilliTime {
	return UnixMilliTime(t.Time().AddDate(years, months, days))
}

func (t UnixMilliTime) Unix() int64 {
	return t.Time().Unix()
}

func (t UnixMilliTime) UnixMilli() int64 {
	return t.Time().UnixMilli()
}

func (t UnixMilliTime) UnixMicro() int64 {
	return t.Time().UnixMicro()
}

func (t UnixMilliTime) UnixNano() int64 {
	return t.Time().UnixNano()
}

func (t UnixMilliTime) Format(layout string) string {
	return t.Time().Format(layout)
}

func (t UnixMilliTime) GoString() string {
	return t.Time().GoString()
}

func (t UnixMilliTime) String() string {
	return t.Time().String()
}

func (t UnixMilliTime) Location() *time.Location {
	return t.Time().Location()
}

func NewUnixMilli(t time.Time) UnixMilliTime {
	return UnixMilliTime(t)
}

func NowUnixMilli() UnixMilliTime {
	return UnixMilliTime(time.Now())
}
