using Microsoft.Extensions.Options;
using MongoDB.Driver;
using StellaOps.Scanner.Storage.Catalog;

namespace StellaOps.Scanner.Storage.Mongo;

public sealed class MongoCollectionProvider
{
    private readonly IMongoDatabase _database;
    private readonly MongoOptions _options;

    public MongoCollectionProvider(IMongoDatabase database, IOptions<ScannerStorageOptions> options)
    {
        _database = database ?? throw new ArgumentNullException(nameof(database));
        _options = (options ?? throw new ArgumentNullException(nameof(options))).Value.Mongo;
    }

    public IMongoCollection<ArtifactDocument> Artifacts => GetCollection<ArtifactDocument>(ScannerStorageDefaults.Collections.Artifacts);
    public IMongoCollection<ImageDocument> Images => GetCollection<ImageDocument>(ScannerStorageDefaults.Collections.Images);
    public IMongoCollection<LayerDocument> Layers => GetCollection<LayerDocument>(ScannerStorageDefaults.Collections.Layers);
    public IMongoCollection<LinkDocument> Links => GetCollection<LinkDocument>(ScannerStorageDefaults.Collections.Links);
    public IMongoCollection<JobDocument> Jobs => GetCollection<JobDocument>(ScannerStorageDefaults.Collections.Jobs);
    public IMongoCollection<LifecycleRuleDocument> LifecycleRules => GetCollection<LifecycleRuleDocument>(ScannerStorageDefaults.Collections.LifecycleRules);

    private IMongoCollection<TDocument> GetCollection<TDocument>(string name)
    {
        var database = _database;

        if (_options.UseMajorityReadConcern)
        {
            database = database.WithReadConcern(ReadConcern.Majority);
        }

        if (_options.UseMajorityWriteConcern)
        {
            database = database.WithWriteConcern(WriteConcern.WMajority);
        }

        return database.GetCollection<TDocument>(name);
    }
}
