/// <summary>
 /// Determines whether the repository is available.
 /// </summary>
 private bool DetermineIsAvailable()
 {
     using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
     {
         var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
         return(repository.IsAvailable());
     }
 }
        //TODO: Currently used in testing only, not part of the interface, need to add queryable methods to the interface instead
        internal IEnumerable <IAuditEntry> GetAll()
        {
            if (_isAvailable.Value == false)
            {
                return(Enumerable.Empty <IAuditEntry>());
            }

            using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
            {
                var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
                return(repository.GetAll());
            }
        }
        //TODO: Currently used in testing only, not part of the interface, need to add queryable methods to the interface instead
        internal IEnumerable <IAuditEntry> GetPage(long pageIndex, int pageCount, out long records)
        {
            if (_isAvailable.Value == false)
            {
                records = 0;
                return(Enumerable.Empty <IAuditEntry>());
            }

            using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
            {
                var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
                return(repository.GetPage(pageIndex, pageCount, out records));
            }
        }
        /// <inheritdoc />
        public IAuditEntry Write(int performingUserId, string perfomingDetails, string performingIp, DateTime eventDateUtc, int affectedUserId, string affectedDetails, string eventType, string eventDetails)
        {
            if (performingUserId < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(performingUserId));
            }
            if (string.IsNullOrWhiteSpace(perfomingDetails))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(perfomingDetails));
            }
            if (string.IsNullOrWhiteSpace(eventType))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(eventType));
            }
            if (string.IsNullOrWhiteSpace(eventDetails))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(eventDetails));
            }

            //we need to truncate the data else we'll get SQL errors
            affectedDetails = affectedDetails?.Substring(0, Math.Min(affectedDetails.Length, AuditEntryDto.DetailsLength));
            eventDetails    = eventDetails.Substring(0, Math.Min(eventDetails.Length, AuditEntryDto.DetailsLength));

            //validate the eventType - must contain a forward slash, no spaces, no special chars
            var eventTypeParts = eventType.ToCharArray();

            if (eventTypeParts.Contains('/') == false || eventTypeParts.All(c => char.IsLetterOrDigit(c) || c == '/' || c == '-') == false)
            {
                throw new ArgumentException(nameof(eventType) + " must contain only alphanumeric characters, hyphens and at least one '/' defining a category");
            }
            if (eventType.Length > AuditEntryDto.EventTypeLength)
            {
                throw new ArgumentException($"Must be max {AuditEntryDto.EventTypeLength} chars.", nameof(eventType));
            }
            if (performingIp != null && performingIp.Length > AuditEntryDto.IpLength)
            {
                throw new ArgumentException($"Must be max {AuditEntryDto.EventTypeLength} chars.", nameof(performingIp));
            }

            var entry = new AuditEntry
            {
                PerformingUserId  = performingUserId,
                PerformingDetails = perfomingDetails,
                PerformingIp      = performingIp,
                EventDateUtc      = eventDateUtc,
                AffectedUserId    = affectedUserId,
                AffectedDetails   = affectedDetails,
                EventType         = eventType,
                EventDetails      = eventDetails
            };

            if (_isAvailable.Value == false)
            {
                return(entry);
            }

            using (var uow = UowProvider.GetUnitOfWork())
            {
                var repository = RepositoryFactory.CreateAuditEntryRepository(uow);
                repository.AddOrUpdate(entry);
                uow.Commit();
            }

            return(entry);
        }