package worldLocations

import "testing"

import "seekia/internal/helpers"


func TestLocations(t *testing.T){

	err := InitializeWorldLocationsVariables()
	if (err != nil){
		t.Fatal("Failed to initialize world locations variables: " + err.Error())
	}

	allCountryObjectsList, err := GetAllCountryObjectsList()
	if (err != nil){
		t.Fatal("Failed to get all country objects list: " + err.Error())
	}

	// We make sure there are no duplicates in the countries list
	allCountryIdentifiersMap := make(map[int]struct{})
	allCountryNamesMap := make(map[string]struct{})

	for _, countryObject := range allCountryObjectsList{

		countryIdentifier := countryObject.Identifier

		_, exists := allCountryIdentifiersMap[countryIdentifier]
		if (exists == true){

			countryIdentifierString := helpers.ConvertIntToString(countryIdentifier)
	
			t.Fatal("Duplicate country identifier found: " + countryIdentifierString)
		}

		allCountryIdentifiersMap[countryIdentifier] = struct{}{}
		
		isValid := VerifyCountryIdentifier(countryIdentifier)
		if (isValid == false){
			t.Fatal("VerifyCountryIdentifier returning invalid for existing countryIdentifier.")
		}

		countryNamesList := countryObject.NamesList	

		for _, countryName := range countryNamesList{

			_, exists := allCountryNamesMap[countryName]
			if (exists == true){
				t.Fatal("Duplicate country name found: " + countryName)
			}
			allCountryNamesMap[countryName] = struct{}{}
		}
	}

	// We use this map to make sure no cities share the same coordinates
	allCityObjectsMap := make(map[CoordinatesObject]struct{})	

	allCityObjectsList, err := getAllCityObjectsList()
	if (err != nil){
		t.Fatal("Failed to get all city objects list: " + err.Error())
	}

	for _, cityObject := range allCityObjectsList{

		cityName := cityObject.Name
		cityState := cityObject.State
		cityCountry := cityObject.Country
		cityLatitude := cityObject.Latitude
		cityLongitude := cityObject.Longitude

		// We make sure that all locations correspond to the countries we have
		_, exists := allCountryNamesMap[cityCountry]
		if (exists == false){
			t.Fatal("City objects contain a country not in the countries list: " + cityCountry)
		}

		// We make sure state/city fields are not empty
		if (cityState == ""){
			t.Fatal("City object contains a city with an empty State.")
		}
		if (cityName == ""){
			t.Fatal("City object contains a city with an empty Name.")
		}

		// We make sure all cities contain unique coordinates
		coordinatesObject := CoordinatesObject{
			Latitude: cityLatitude,
			Longitude: cityLongitude,
		}

		_, exists = allCityObjectsMap[coordinatesObject]
		if (exists == true){

			t.Fatal("Two cities share the same coordinates:" + cityName)
		}

		allCityObjectsMap[coordinatesObject] = struct{}{}
	}
}



