package main import ( "errors" "fmt" "strconv" "strings" "github.com/helmbold/richgo/regexp" ) var ( errIncompatibleTopicPart = errors.New("Incompatible topic part") rxTopicPart = regexp.MustCompile(`\s*\x02` + `\s*\x03\s*(?P[0-9]+)` + `(?P[A-Za-z\s]+):` + `\s*\x03` + `\s*(?P.+)` + `\s*\x02` + `\s*`) rxMatch = regexp.MustCompile(`^` + `(?P` + `\w+(?:\s+\w+)*)` + `\s+(?P\-|\d+):(?P\-|\d+)` + `\s+(?P\w+(?:\s+\w+)*)` + `(` + `\s+(?P.+)` + `)?` + `$`) rxAdditionalScoreInfo = regexp.MustCompile(`^` + `(?P
.*?)\s*` +
		`(\[(?:` +
		`(?PP)\s*(?P\d+:\d+)` +
		`|` +
		`(?PAET)` +
		`)\]\s*)?` +
		`\((?P\d+:\d+)\)` +
		`\s*(?P.*)` +
		`$`)
)

type topicPart struct {
	PrefixColor string
	Prefix      string

	Text    string
	Matches []topicMatchInfo
}

func (t *topicPart) HasMatches() bool {
	return t.Matches != nil && len(t.Matches) > 0
}

func (t *topicPart) String() string {
	retval := fmt.Sprintf("\x02\x03%s%s:\x03 ", t.PrefixColor, t.Prefix)
	if t.Matches == nil || len(t.Matches) == 0 {
		retval += t.Text
	} else {
		first := true
		for _, match := range t.Matches {
			if !first {
				retval += " + "
			}
			retval += match.String()
			first = false
		}
	}
	retval += "\x02"
	return retval
}

type topicMatchInfo struct {
	HomeTeam   string
	AwayTeam   string
	Current    *topicScoreInfo
	Additional string
}

type topicAdditionalScoreInfo struct {
	IsAET     bool
	PenScore  string
	HalfScore string

	Pre  string
	Post string
}

func (i *topicAdditionalScoreInfo) String() string {
	retval := ""
	switch {
	case len(i.PenScore) > 0:
		retval += fmt.Sprintf("[P %s]", i.PenScore)
	case i.IsAET:
		retval += "[AET]"
	}
	if len(retval) > 0 {
		retval += " "
	}
	if len(i.HalfScore) > 0 {
		retval += fmt.Sprintf("(%s)", i.HalfScore)
	}

	if len(i.Pre) > 0 {
		if len(retval) > 0 {
			retval = " " + retval
		}
		retval = i.Pre + retval
	}

	if len(i.Post) > 0 {
		if len(retval) > 0 {
			retval += " "
		}
		retval += i.Post
	}
	return retval
}

func (m *topicMatchInfo) AdditionalScoreInfo() *topicAdditionalScoreInfo {
	a := rxAdditionalScoreInfo.Match(m.Additional)
	if a == nil {
		return nil
	}

	return &topicAdditionalScoreInfo{
		HalfScore: a.NamedGroups["halfScore"],
		IsAET:     len(a.NamedGroups["penScore"]) > 0 || len(a.NamedGroups["extraTag"]) > 0,
		PenScore:  a.NamedGroups["penScore"],

		Pre:  a.NamedGroups["pre"],
		Post: a.NamedGroups["post"],
	}
}

func (m *topicMatchInfo) String() string {
	retval := fmt.Sprintf("%s %s %s", m.HomeTeam, m.Current, m.AwayTeam)
	if len(m.Additional) > 0 {
		retval += " " + m.Additional
	}
	return retval

}

type topicScoreInfo struct {
	HomeScore int
	AwayScore int
}

func (s *topicScoreInfo) String() string {
	if s == nil {
		return "-:-"
	}
	return fmt.Sprintf("%d:%d", s.HomeScore, s.AwayScore)
}

func parseTopicPart(s string) (r topicPart, err error) {
	match := rxTopicPart.Match(s)
	if match == nil {
		err = errIncompatibleTopicPart
		return
	}
	r.PrefixColor = match.NamedGroups["prefixColor"]
	r.Prefix = match.NamedGroups["prefix"]
	r.Text = match.NamedGroups["text"]

	// Try to get match info if compatible
	matchCompatible := true
	matchInfos := []topicMatchInfo{}
	for _, matchPart := range strings.Split(r.Text, " + ") {
		match = rxMatch.Match(matchPart)
		if match == nil {
			matchCompatible = false
			break
		}
		matchInfo := topicMatchInfo{}
		matchInfo.HomeTeam = match.NamedGroups["homeTeam"]
		matchInfo.AwayTeam = match.NamedGroups["awayTeam"]
		homeScore, err := strconv.Atoi(match.NamedGroups["homeScore"])
		if err == nil {
			awayScore, err := strconv.Atoi(match.NamedGroups["awayScore"])
			if err == nil {
				matchInfo.Current = &topicScoreInfo{
					HomeScore: homeScore,
					AwayScore: awayScore,
				}
			}
		}
		matchInfo.Additional = match.NamedGroups["additional"]
		matchInfos = append(matchInfos, matchInfo)
	}
	if matchCompatible {
		r.Matches = matchInfos
	}
	return
}