package mo

import (
	"context"
	"reflect"
	"testing"
)

func TestNewClient(t *testing.T) {
	client, err := Dial("mongodb://root:abcd1234@localhost:27017/?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false")
	if err != nil {
		t.Error(err)
		return
	}
	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimout)
	defer cancel()

	// opts := options.CreateCollection().SetValidator(validator)

	cmd := D{{Key: "collMod", Value: "user"}, {Key: "validator", Value: E{Key: "$jsonSchema", Value: M{
		"bsonType": "object",
		"required": []string{"password"},
		"properties": M{
			"username": M{
				"bsonType":    "string",
				"description": "must be a string and is required",
			},
			"password": M{
				"bsonType":    "long",
				"description": "must be a long and is required",
			},
		},
	}}}}

	r := client.Database("ums").RunCommand(ctx, cmd)
	if err := r.Err(); err != nil {
		t.Error(err)
	}
}

func TestNewObjectID(t *testing.T) {
	t.Log(ID.New().Hex())
}

const (
	moTestSimpleDb   = "test"
	moTestSimpleColl = moTestSimpleDb
)

func newSimple() *Collection {
	client, err := Dial("mongodb://root:abcd1234@192.168.0.224:27017/?authSource=admin&readPreference=primary&appname=golandTest&directConnection=true&ssl=false")
	if err != nil {
		panic(err)
	}
	return client.Database(moTestSimpleDb).Collection(moTestSimpleColl)
}

func ctxTimeout() context.Context {
	ctx, cancel := context.WithTimeout(context.Background(), DefaultTimout)
	go func() {
		<-ctx.Done()
		cancel()
	}()
	return ctx
}

func TestSimple_InsertOne(t *testing.T) {
	sim := newSimple()
	testData := M{
		"name":    "xiaoming",
		"age":     10,
		"hobby":   "learning to mongodb",
		"enabled": true,
	}
	ret, err := sim.InsertOne(ctxTimeout(), testData)
	if err != nil {
		t.Error(err)
		return
	}
	t.Log(ret.InsertedID, reflect.TypeOf(ret.InsertedID).Kind())
}

func TestSimple_InsertMany(t *testing.T) {
	sim := newSimple()
	testData := []any{
		M{
			"name":    "lihua",
			"age":     11,
			"hobby":   "music",
			"enabled": true,
		},
		M{
			"name":    "amy",
			"age":     12,
			"hobby":   "sport",
			"enabled": false,
		},
	}
	ret, err := sim.InsertMany(ctxTimeout(), testData)
	if err != nil {
		t.Error(err)
		return
	}
	t.Log(ret.InsertedIDs, reflect.TypeOf(ret.InsertedIDs).Kind())
}

func TestSimple_Indexes(t *testing.T) {
	sim := newSimple()
	idxRet, err := sim.Indexes().CreateOne(context.Background(), NewIndex("idxa", true))
	if err != nil {
		t.Error("CreateOne:", err)
		return
	}
	t.Log(idxRet)

	cursor, err := sim.Indexes().List(context.Background())
	if err != nil {
		t.Error(err)
		return
	}

	idxList, err := ResolveIndexName(cursor)
	if err != nil {
		t.Error(err)
		return
	}
	t.Log(idxList)

	err = sim.Indexes().DropOne(context.Background(), IndexName("idxa"))
	if err != nil {
		t.Error(err)
		return
	}
}
