package scraping

// A library to grab match data from The Blue Alliance.
import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strconv"
)

// Stores the TBA API key to access the API.
type scrapingConfig struct {
	ApiKey    string `json:"api_key"`
	BaseUrl   string `json:"base_url"`
	Year      int32  `json:"year"`
	EventCode string `json:"event_code"`
}

// Takes in year and FIRST event code and returns requested information according to TBA.
// Also takes in a file path to the JSON config file that contains your TBA API key.
// It defaults to <workspace root>/config.json
// the config is expected to have the following contents:
//
//	{
//	   api_key:"myTBAapiKey"
//	}
func getJson(year int32, eventCode, configPath, category string) ([]byte, error) {
	if configPath == "" {
		configPath = os.Getenv("BUILD_WORKSPACE_DIRECTORY") + "/scouting_config.json"
	}

	// Takes the filepath and grabs the api key from the json.
	content, err := ioutil.ReadFile(configPath)
	if err != nil {
		return nil, errors.New(fmt.Sprint("Failed to open config at ", configPath, ": ", err))
	}
	// Parses the JSON parameters into a struct.
	var config scrapingConfig
	if err := json.Unmarshal([]byte(content), &config); err != nil {
		return nil, errors.New(fmt.Sprint("Failed to parse config file as JSON: ", err))
	}

	// Perform some basic validation on the data.
	if config.ApiKey == "" {
		return nil, errors.New("Missing 'api_key' in config JSON.")
	}
	if config.BaseUrl == "" {
		config.BaseUrl = "https://www.thebluealliance.com"
	}
	if config.Year == 0 {
		config.Year = year
	}
	if config.EventCode == "" {
		config.EventCode = eventCode
	}

	// Create the TBA event key for the year and event code.
	eventKey := strconv.Itoa(int(config.Year)) + config.EventCode

	// Create a get request for the match info.
	req, err := http.NewRequest("GET", config.BaseUrl+"/api/v3/event/"+eventKey+"/"+category, nil)
	if err != nil {
		return nil, errors.New(fmt.Sprint("Failed to build http request: ", err))
	}

	// Add the auth key header to the request.
	req.Header.Add("X-TBA-Auth-Key", config.ApiKey)

	// Make the API request.
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, errors.New(fmt.Sprint("Failed to make TBA API request: ", err))
	}

	defer resp.Body.Close()
	if resp.StatusCode != 200 {
		return nil, errors.New(fmt.Sprint("Got unexpected status code from TBA API request ", req.URL, ": ", resp.Status))
	}

	// Get all bytes from response body.
	bodyBytes, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, errors.New(fmt.Sprint("Failed to read TBA API response: ", err))
	}

	return bodyBytes, nil
}

func GetAllData[T interface{}](year int32, eventCode, configPath string, category string) (T, error) {
	var result T
	bodyBytes, err := getJson(year, eventCode, configPath, category)
	if err != nil {
		return result, err
	}

	// Unmarshal the JSON data into the in-memory format.
	if err = json.Unmarshal([]byte(bodyBytes), &result); err != nil {
		return result, errors.New(fmt.Sprint("Failed to parse ", category, " JSON received from TBA: ", err))
	}

	return result, nil
}
