using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using EasyCaching.Core.Configurations;
using EasyCaching.Serialization.SystemTextJson.Configurations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using XF.Domain.Cache;

namespace Hotline.EasyCaching
{
    public static class StartupExtensions
    {
        public static IServiceCollection AddCache(this IServiceCollection services, Action<CacheOptions> action)
        {
            var options = new CacheOptions();
            action(options);

            services.AddEasyCaching(d =>
            {
                d.WithSystemTextJson("xjson");

                // local
                d.UseInMemory("m1");

                d.UseRedis(config =>
                {
                    config.DBConfig.Endpoints.Add(new ServerEndPoint(options.ConnectionString, options.Port));
                    config.DBConfig.Database = options.Database;
                    config.SerializerName = "xjson";
                }, "r1");

                // combine local and distributed
                d.UseHybrid(config =>
                    {
                        config.TopicName = "hotline-topic";
                        config.EnableLogging = false;

                        // specify the local cache provider name after v0.5.4
                        config.LocalCacheProviderName = "m1";
                        // specify the distributed cache provider name after v0.5.4
                        config.DistributedCacheProviderName = "r1";
                    }, "h1")
                    // use redis bus
                    .WithRedisBus(busConf =>
                    {
                        busConf.Endpoints.Add(new ServerEndPoint(options.ConnectionString, options.Port));

                        // do not forget to set the SerializerName for the bus here !!
                        busConf.SerializerName = "xjson";
                    });
            })
                    .Configure(action)
                    .AddSingleton(typeof(ITypedCache<>), typeof(DefaultTypedCache<>))
                ;

            return services;
        }
    }

    public class CacheOptions
    {
        public string ConnectionString { get; set; }

        public int Port { get; set; }

        public int Database { get; set; } = 1;

        public string Prefix { get; set; }

        public int MaxRdSecond { get; set; }
    }
}
