Skip to content
Snippets Groups Projects
Select Git revision
  • 12a76b6baadabddf4bdeb0618b145a27352fc91d
  • master default protected
  • Eilerts_branch
  • Karins_branch
  • Mads_branch
5 results

DB.class

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    supported_countries.go 3.33 KiB
    package _func
    
    import (
    	"encoding/json"
    	"errors"
    	"fmt"
    	"globeboard/internal/utils/constants/External"
    	"globeboard/internal/utils/structs"
    	"golang.org/x/text/cases"
    	"golang.org/x/text/language"
    	"net/http"
    	"strings"
    	"time"
    )
    
    // getSupportedCountries fetches countries with their common names and cca2 codes.
    func getSupportedCountries() (map[string]string, error) {
    	url := fmt.Sprintf("%sall?fields=name,cca2", External.CountriesAPI)
    	var responseData []struct {
    		Name struct {
    			Common string `json:"common"`
    		} `json:"name"`
    		CCA2 string `json:"cca2"`
    	}
    
    	client := &http.Client{Timeout: 10 * time.Second}
    	req, err := http.NewRequest(http.MethodGet, url, nil)
    	if err != nil {
    		return nil, fmt.Errorf("error creating request: %v", err)
    	}
    	req.Header.Add("content-type", "application/json")
    
    	res, err := client.Do(req)
    	if err != nil {
    		return nil, fmt.Errorf("error issuing request: %v", err)
    	}
    
    	err = json.NewDecoder(res.Body).Decode(&responseData)
    	if err != nil {
    		return nil, fmt.Errorf("error decoding JSON: %v", err)
    	}
    
    	countriesMap := make(map[string]string)
    	for _, item := range responseData {
    		countriesMap[item.CCA2] = item.Name.Common
    	}
    	return countriesMap, nil
    }
    
    func ValidateCountryInfo(ci *structs.CountryInfoGet) error {
    	err := validateCountryNameIsoCode(ci)
    	if err != nil {
    		return err
    	}
    
    	if !ci.Features.Temperature && !ci.Features.Precipitation && !ci.Features.Capital &&
    		!ci.Features.Coordinates && !ci.Features.Population && !ci.Features.Area {
    		return errors.New("at least one feature must be true")
    	}
    	return nil
    }
    
    func validateCountryNameIsoCode(ci *structs.CountryInfoGet) error {
    	validCountries, err := getSupportedCountries() // Adjusted to use the map version.
    	if err != nil {
    		return errors.New("error validating country")
    	}
    
    	if err := validateCountryOrIsoCodeProvided(ci); err != nil {
    		return err
    	}
    
    	if err := validateIsoCode(ci, validCountries); err != nil {
    		return err
    	}
    
    	if err := updateAndValidateIsoCodeForCountry(ci, validCountries); err != nil {
    		return err
    	}
    
    	return validateCorrespondence(ci, validCountries)
    }
    
    func validateCountryOrIsoCodeProvided(ci *structs.CountryInfoGet) error {
    	if ci.Country == "" && ci.IsoCode == "" {
    		return errors.New("either country name or ISO code must be provided")
    	}
    	return nil
    }
    
    func validateIsoCode(ci *structs.CountryInfoGet, validCountries map[string]string) error {
    	if ci.IsoCode != "" {
    		ci.IsoCode = strings.ToTitle(ci.IsoCode)
    		if country, exists := validCountries[ci.IsoCode]; !exists {
    			return errors.New("invalid ISO code")
    		} else {
    			ci.Country = country
    		}
    	}
    	return nil
    }
    
    func updateAndValidateIsoCodeForCountry(ci *structs.CountryInfoGet, validCountries map[string]string) error {
    	if ci.IsoCode == "" && ci.Country != "" {
    		ci.Country = cases.Title(language.English, cases.Compact).String(ci.Country)
    		for code, name := range validCountries {
    			if name == ci.Country {
    				ci.IsoCode = code
    				return nil
    			}
    		}
    		return errors.New("country name not valid or not supported")
    	}
    	return nil
    }
    
    func validateCorrespondence(ci *structs.CountryInfoGet, validCountries map[string]string) error {
    	if ci.Country != "" && ci.IsoCode != "" {
    		ci.Country = cases.Title(language.English, cases.Compact).String(ci.Country)
    		if validCountries[ci.IsoCode] != ci.Country {
    			return errors.New("ISO code and country name do not match")
    		}
    	}
    	return nil
    }