public async Task <AutocompleteResultSet> Autocomplete([FromUri] string query, [FromUri] string[] not, [FromUri] string[] teamType, [FromUri] bool includeClubTeams = true)
        {
            if (not is null)
            {
                throw new ArgumentNullException(nameof(not));
            }

            if (teamType is null)
            {
                throw new ArgumentNullException(nameof(teamType));
            }

            var teamQuery = new TeamFilter {
                Query = query
            };

            teamQuery.IncludeClubTeams = includeClubTeams;

            foreach (var guid in not)
            {
                if (guid == null)
                {
                    continue;
                }

                try
                {
                    teamQuery.ExcludeTeamIds.Add(new Guid(guid));
                }
                catch (FormatException)
                {
                    // ignore that one
                }
            }

            foreach (var unparsedType in teamType)
            {
                if (Enum.TryParse <TeamType>(unparsedType, out var parsedType))
                {
                    teamQuery.TeamTypes.Add(parsedType);
                }
            }

            var teams = await _teamDataSource.ReadTeams(teamQuery).ConfigureAwait(false);

            return(new AutocompleteResultSet
            {
                suggestions = teams.Select(x => new AutocompleteResult
                {
                    value = (x.UntilYear.HasValue ? x.TeamName + " (no longer active)" : x.TeamName),
                    data = x.TeamId.ToString()
                })
            });
        }
        public async override Task <bool> PerformRunAsync(CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                _logger.Warn(GetType(), "Background task cancellation requested in {Type:l}.", GetType());
                return(false);
            }

            _logger.Info <SpogoCsvExportTask>(nameof(SpogoCsvExportTask) + " running");

            var teams = (await _teamDataSource.ReadTeams(new TeamFilter
            {
                ActiveTeams = true,
                TeamTypes = new List <TeamType?> {
                    TeamType.Regular
                }
            }).ConfigureAwait(false)).Select(x => new SpogoCsvRecord
            {
                TeamId             = x.TeamId.Value.GetHashCode() > 0 ? x.TeamId.Value.GetHashCode() : x.TeamId.Value.GetHashCode() * -1,
                TeamName           = x.TeamName + " Stoolball Club",
                Description        = FormatTeamDescription(x),
                PlayerType         = x.PlayerType.Humanize(),
                HomeGroundName     = x.MatchLocations.FirstOrDefault()?.Name(),
                StreetName         = x.MatchLocations.FirstOrDefault()?.StreetDescription,
                Locality           = x.MatchLocations.FirstOrDefault()?.Locality,
                Town               = x.MatchLocations.FirstOrDefault()?.Town,
                AdministrativeArea = x.MatchLocations.FirstOrDefault()?.AdministrativeArea,
                Postcode           = x.MatchLocations.FirstOrDefault()?.Postcode,
                Country            = "England",
                Latitude           = x.MatchLocations.FirstOrDefault()?.Latitude,
                Longitude          = x.MatchLocations.FirstOrDefault()?.Longitude,
                Website            = !string.IsNullOrWhiteSpace(x.Website) ? x.Website : "https://www.stoolball.org.uk" + x.TeamRoute,
                ContactEmail       = _contactDetailsParser.ParseFirstEmailAddress(x.PublicContactDetails),
                ContactPhone       = _contactDetailsParser.ParseFirstPhoneNumber(x.PublicContactDetails)
            }).Where(x => !string.IsNullOrEmpty(x.ContactEmail) || !string.IsNullOrEmpty(x.ContactPhone)).ToList();

            var path = Path.Combine(HostingEnvironment.ApplicationPhysicalPath, @"App_Data\csv");

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            using (var writer = new StreamWriter(Path.Combine(path, "spogo-protected.csv")))
            {
                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                {
                    csv.WriteRecords(teams);
                }
            }

            foreach (var team in teams)
            {
                team.ContactEmail = team.ContactPhone = string.Empty;
            }
            using (var writer = new StreamWriter(Path.Combine(path, "spogo.csv")))
            {
                using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
                {
                    csv.WriteRecords(teams);
                }
            }

            // Keep repeating
            return(true);
        }