static void PrintResultsToDisk(GeoLocationResult result)
        {
            string json = JsonConvert.SerializeObject(result);

            //Defaults to: ..\repos\RailtownBE5Assignment\RailtownBE5Assignment\RailtownBE5Assignment\bin\Debug
            File.AppendAllText($"{Directory.GetCurrentDirectory()}/output.json", json);
        }
        public GeoLocationResult GetGeoLocation(IPAddress address, NameValueCollection config)
        {
            string text = config["databaseFileName"];

            if (!string.IsNullOrEmpty(text))
            {
                maxMindDatabaseFileName = VirtualPathUtilityEx.RebasePhysicalPath(text);
                config.Remove("databaseFileName");
            }

            if (string.IsNullOrWhiteSpace(maxMindDatabaseFileName))
            {
                throw new ArgumentException("db name is not provided");
            }

            if (!System.IO.File.Exists(maxMindDatabaseFileName))
            {
                throw new ArgumentException(string.Format("db does not exist at location {0}", maxMindDatabaseFileName));
            }

            if (address.AddressFamily != AddressFamily.InterNetwork &&
                address.AddressFamily != AddressFamily.InterNetworkV6)
            {
                return(null);
            }

            try
            {
                using (var reader = new DatabaseReader(maxMindDatabaseFileName))
                {
                    var dbResult = reader.City(address);

                    if (dbResult == null)
                    {
                        return(null);
                    }

                    GeoLocationResult result = new GeoLocationResult();
                    result.CountryCode    = dbResult.Country.IsoCode;
                    result.CountryName    = dbResult.Country.Name;
                    result.Latitude       = dbResult.Location.Latitude ?? 0;
                    result.Longitude      = dbResult.Location.Longitude ?? 0;
                    result.MetroCode      = dbResult.Location.MetroCode ?? 0;
                    result.City           = dbResult.City.Name;
                    result.PostalCode     = dbResult.Postal.Code;
                    result.CountinentCode = dbResult.Continent.Code;
                    result.Region         = dbResult?.MostSpecificSubdivision?.IsoCode;
                    result.RegionName     = dbResult.MostSpecificSubdivision?.Name;
                    return(result);
                }
            }
            catch (Exception ex)
            {
                throw;
            }
        }
        public async Task GetFarthestDistance()
        {
            IGeoLocationService service = new GeoLocationService();

            GeoLocationResult result = service.GetFarthestUsers(CreateMockUsers());

            Assert.Equal("Vancouver", result.UserOne.Name);
            Assert.Equal("Toronto", result.UserTwo.Name);

            //Google says 3364 km
            //Searched "distance from vancouver to toronto by flight"

            //https://www.movable-type.co.uk/scripts/latlong.html says 3362 km with
            //Toronto : 43 39 3.8 N, 79 20 49.2 W
            //Vancouver : 49 14 46.6 N, 123 6 58.4 W
            Assert.Equal(3362, Math.Round(result.Distance));
        }
        static async Task CalculateResults()
        {
            ServiceProvider provider = ConfigureServices();

            ILocationServiceAdapter locationAdapter = provider.GetService <ILocationServiceAdapter>();
            IGeoLocationService     geoService      = provider.GetService <IGeoLocationService>();

            IUser[] users = await locationAdapter.GetUsers("https://jsonplaceholder.typicode.com/users");

            GeoLocationResult result = geoService.GetFarthestUsers(users);

            Console.WriteLine($"Farthest distance is: {result.Distance} km");

            Console.WriteLine();
            result.UserOne.PrintUser();

            Console.WriteLine();
            result.UserTwo.PrintUser();

            PrintResultsToDisk(result);
        }