package main

import (
	"encoding/json"
	"fmt"
	"html"
	"strings"
	"time"
)

type ObjectID string

type TwitterError struct {
	Code    int64
	Message string
	Label   string
}

type TwitterTime struct {
	time.Time
}

func (twt *TwitterTime) UnmarshalJSON(b []byte) error {
	s := strings.Trim(string(b), "\"")
	var err error
	twt.Time, err = time.Parse(time.RubyDate, s)
	return err
}

type Entities struct {
	Media []Media
}

type Media struct {
	Media_url string
}

type StatusUser struct {
	Name        string
	Screen_name string
}

type Status struct {
	Errors                    []TwitterError
	Full_text                 string
	Id_str                    string
	Created_at                TwitterTime
	In_reply_to_screen_name   string
	In_reply_to_status_id_str string
	User                      StatusUser
	Quoted_status             *Status
	Retweeted_status          *Status
	Extended_entities         Entities
	//only available in premium API  	Quote_count               int64
	//only available in premium API  	Reply_count               int64
	Retweet_count  int64
	Favorite_count int64
}

func (t Status) Error() string {
	if len(t.Errors) == 0 {
		return ""
	} else {
		s, _ := json.Marshal(t)
		return "Response error " + string(s)
	}
}

func (t Status) equals(t2 Status) bool {
	return t.Id_str == t2.Id_str
}

func equals(t1 []Status, t2 []Status) bool {
	if len(t1) != len(t2) {
		return false
	}
	for i := range t1 {
		if !t1[i].equals(t2[i]) {
			return false
		}
	}
	return true
}

func (t Status) InReplyTo() string {
	if t.In_reply_to_status_id_str != "" {
		return t.In_reply_to_screen_name + " (" + t.In_reply_to_status_id_str + ")"
	} else {
		return ""
	}
}

func (t Status) Text() string {
	return html.UnescapeString(t.Full_text)
}

func (t Status) String() string {
	if t.Retweeted_status != nil {
		return t.User.Screen_name + " retweeted " + t.Retweeted_status.String()
	}
	s := t.User.Screen_name + " " + "(" + t.Id_str + ")" + fmt.Sprintf(" (rt:%d,fav:%d)", t.Retweet_count, t.Favorite_count)
	if replyTo := t.InReplyTo(); replyTo != "" {
		s += " in reply to " + replyTo
	}
	s += ":\n" + t.Text()
	allMedia := t.Extended_entities.Media
	if len(allMedia) > 0 {
		s += "\n\nMedia:"
		for _, media := range allMedia {
			s += " " + media.Media_url
		}
	}
	if t.Quoted_status != nil {
		s += "\n\nQuotes " + t.Quoted_status.String()
	}
	return s
}

func (t Status) URL() string {
	return "https://twitter.com/" + t.User.Screen_name + "/status/" + t.Id_str
}