using Application;
using Domain;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Infrastructure
{
  public static class ServiceCollectionExtensions
  {
    public static IServiceCollection AddHNServicesEF(this IServiceCollection services)
    {
      services.AddDbContext<HNDbContext>((provider, options) =>
      {
        var configuration = provider.GetRequiredService<IConfiguration>();

        options.UseSqlite(configuration.GetConnectionString("Default"));
      });

      services.AddScoped<ILinkRepository, Infrastructure.Repositories.EntityFramework.LinkRepository>();
      services.AddScoped<ICommentRepository, Infrastructure.Repositories.EntityFramework.CommentRepository>();
      services.AddScoped<IData, HNDbContext>();

      return services.AddCommon();
    }

    public static IServiceCollection AddHNServicesInMemory(this IServiceCollection services)
    {
      var link1 = new Domain.Link("http://default.website");
      var link2 = new Domain.Link("http://another.website");
      var link3 = new Domain.Link("http://a.final.website");

      services.AddSingleton<ILinkRepository>(new Infrastructure.Repositories.Memory.LinkRepository(
        link1,
        link2,
        link3
      ));
      services.AddSingleton<ICommentRepository>(new Infrastructure.Repositories.Memory.CommentRepository(
        link1.AddComment("my first comment"),
        link3.AddComment("another comment")
      ));
      services.AddSingleton<IData>(serviceProvider =>
      {
        var memoryLinkRepository = serviceProvider.GetRequiredService<ILinkRepository>() as Infrastructure.Repositories.Memory.LinkRepository;
        var memoryCommentRepository = serviceProvider.GetRequiredService<ICommentRepository>() as Infrastructure.Repositories.Memory.CommentRepository;
        return new Infrastructure.Repositories.Memory.Data(memoryLinkRepository, memoryCommentRepository);
      });


      return services.AddCommon();
    }

    private static IServiceCollection AddCommon(this IServiceCollection services)
    {
      services.AddTransient<LinkService>();
      services.AddTransient<CommentService>();

      return services;
    }
  }
}