﻿using System;
using EasyApi.Storages;
using EasyApi.Utils;

namespace EasyApi.Metadata.Providers
{
	public class CachedServiceMetadataProvider : IServiceMetadataProvider
	{
		private static readonly TimeSpan _defaultCacheExpirationPeriod = TimeSpan.FromMinutes(10);

		private readonly IServiceMetadataProvider _internalProvider;
		private readonly IStorage<Type> _metadataCache;
		private readonly IEntryExpirationStrategy _cacheExpirationStrategy;

		public CachedServiceMetadataProvider(IServiceMetadataProvider internalProvider, TimeSpan cacheExpirationPeriod)
		{
			Argument.IsNotNull(internalProvider, nameof(internalProvider));
			Argument.IsValidPeriod(cacheExpirationPeriod, nameof(cacheExpirationPeriod));

			_internalProvider = internalProvider;
			_metadataCache = new Storage<Type>();
			_cacheExpirationStrategy = EntryExpiration.Sliding(cacheExpirationPeriod);
		}

		public CachedServiceMetadataProvider(IServiceMetadataProvider internalProvider)
			: this(internalProvider, _defaultCacheExpirationPeriod)
		{
		}

		public IServiceMetadata GetMetadata(Type serviceType)
		{
			Argument.IsNotNull(serviceType, nameof(serviceType));

			return _metadataCache.GetOrSet(serviceType, _internalProvider.GetMetadata, _cacheExpirationStrategy);
		}
	}
}