package logger

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"strconv"
	"time"
)

var (
	collectionMap map[string]*mongo.Collection
)

func NewMongoDriver(config db, level int) (driver, error) {
	if collectionMap == nil {
		collectionMap = make(map[string]*mongo.Collection)
	}
	var collection *mongo.Collection
	mKey := config.Host + strconv.Itoa(config.Port) + config.Database + config.Table
	collection = collectionMap[mKey]
	if collection == nil {
		ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
		client, err := mongo.Connect(ctx, options.Client().ApplyURI(fmt.Sprintf("mongodb://%s:%d", config.Host, config.Port)))
		if err != nil {
			return nil, err
		}
		err = client.Ping(ctx, nil)
		if err != nil {
			return nil, err
		}
		collection = client.Database(config.Database).Collection(config.Table)
		collectionMap[mKey] = collection
	}

	return &mongoLogger{
		level:      level,
		collection: collection,
	}, nil
}

type mongoLogger struct {
	level      int
	collection *mongo.Collection
}

func (m *mongoLogger) Record(message message) {
	if (message.Level == debugLevel || message.Level == DebugLevel) && m.level > debugLevelInt {
		return
	}
	if (message.Level == infoLevel || message.Level == InfoLevel) && m.level > infoLevelInt {
		return
	}
	if (message.Level == warnLevel || message.Level == WarnLevel) && m.level > warnLevelInt {
		return
	}
	if (message.Level == errorLevel || message.Level == ErrorLevel) && m.level > errorLevelInt {
		return
	}
	if (message.Level == fatalLevel || message.Level == FatalLevel) && m.level > fatalLevelInt {
		return
	}
	_, _ = m.collection.InsertOne(context.TODO(), message)
}
