go-discord-bot / internal / tft / tft.go
tft.go
Raw
package tft

import (
	"errors"
	"fmt"
	"log"
	"sync"
	// "github.com/mr1hm/go-discord-bot/internal/tft/api"
)

type TFTData struct {
	Data map[string]AccountMatchData
	Mtx  *sync.RWMutex
}

type TFTDataError struct {
	Err error
}

func (de *TFTDataError) Error() string {
	return fmt.Sprintf("[ API ] Error: %v", de.Err)
}

var (
	UserData TFTData
)

func (td *TFTData) NewData() {
	UserData.Data = make(map[string]AccountMatchData)
	UserData.Mtx = new(sync.RWMutex)
}

func (td *TFTData) Set(field string, id, data interface{}) error {
	// `id` is an interface because we need to process either Player ID or Match ID
	switch field {
	case "account":
		data, data_ok := data.(RiotAccountResponse)
		if !data_ok {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'account' data: %v\n", data_ok)),
			}
		}
		puuid, id_ok := id.(string)
		if !id_ok {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'matches' PUUID: %v", id_ok)),
			}
		}

		UserData.Mtx.Lock()
		UserData.Data[puuid] = AccountMatchData{
			Account:      data,
			MatchDetails: make(map[string]Matchdata),
		}
		UserData.Mtx.Unlock()
	case "matches":
		data, data_ok := data.(RiotMatchesResponse)
		if !data_ok {
			fmt.Printf("Type assertion failed for 'matches': %v\n", data_ok)
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'matches' data: %v", data_ok)),
			}
		}
		puuid, id_ok := id.(string)
		if !id_ok {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'matches' PUUID: %v", id_ok)),
			}
		}

		// Verify that the account exists in our map
		amd, exists := UserData.Data[puuid]
		if !exists {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("PUUID %v, doesn't exist...", puuid)),
			}
		}

		UserData.Mtx.Lock()
		amd.Matches = data
		UserData.Data[puuid] = amd
		UserData.Mtx.Unlock()
		log.Printf("UserData.Data[%v]: %+v", puuid, UserData.Data[puuid].Matches)
	case "match_details":
		data, data_ok := data.(RiotMatchResponse)
		if !data_ok {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'match_details': %v", data_ok)),
			}
		}
		mid, id_ok := id.(string)
		if !id_ok {
			return &TFTDataError{
				Err: errors.New(fmt.Sprintf("Type assertion failed for 'match_details' match ID: %v", id_ok)),
			}
		}

		for puuid, amd := range UserData.Data {
			// Append all match details to matching PUUIDs
			// Loop through match participants and append MatchDetails data by matching PUUID
			for _, resp_participant := range data.GameInfo.Participants {
				if data.Metadata.MatchID == mid {
					if resp_participant.PlayerPUUID == puuid {
						UserData.Mtx.Lock()
						amd.MatchDetails[mid] = Matchdata{
							GameTimePlayed: data.GameInfo.GameDateTime,
							Metadata:       data.Metadata,
							Data:           resp_participant,
						}
						UserData.Data[puuid] = amd
						UserData.Mtx.Unlock()
					}
				}
			}
		}
	default:
		return &TFTDataError{
			Err: errors.New(fmt.Sprintf("Invalid field was given: %v", field)),
		}
	}

	return nil
}