func stringToBool(source string) bool {
	return source == "true"
}
TODO: make it common
package template
import (
	"context"
	"errors"
	"strings"
	"time"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"github.com/koderover/zadig/pkg/microservice/aslan/config"
	"github.com/koderover/zadig/pkg/microservice/aslan/core/common/repository/models/template"
	mongotool "github.com/koderover/zadig/pkg/tool/mongo"
)
type ProductColl struct {
	*mongo.Collection
	coll string
}
func NewProductColl() *ProductColl {
	name := template.Product{}.TableName()
	return &ProductColl{Collection: mongotool.Database(config.MongoDatabase()).Collection(name), coll: name}
}
func (c *ProductColl) GetCollectionName() string {
	return c.coll
}
func (c *ProductColl) EnsureIndex(ctx context.Context) error {
	mod := mongo.IndexModel{
		Keys:    bson.M{"product_name": 1},
		Options: options.Index().SetUnique(true),
	}
	_, err := c.Indexes().CreateOne(ctx, mod)
	return err
}
func (c *ProductColl) Find(productName string) (*template.Product, error) {
	res := &template.Product{}
	query := bson.M{"product_name": productName}
	err := c.FindOne(context.TODO(), query).Decode(res)
	return res, err
}
func (c *ProductColl) FindProjectName(project string) (*template.Product, error) {
	resp := &template.Product{}
	query := bson.M{"project_name": project}
	err := c.FindOne(context.TODO(), query).Decode(resp)
	return resp, err
}
func (c *ProductColl) List() ([]*template.Product, error) {
	var resp []*template.Product
	cursor, err := c.Collection.Find(context.TODO(), bson.M{})
	if err != nil {
		return nil, err
	}
	err = cursor.All(context.TODO(), &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}
func (c *ProductColl) ListNames() ([]string, error) {
	var res []struct {
		ProductName string `bson:"product_name"`
	}
	opts := options.Find()
	projection := bson.D{
		{"product_name", 1},
	}
	opts.SetProjection(projection)
	cursor, err := c.Collection.Find(context.TODO(), bson.M{}, opts)
	if err != nil {
		return nil, err
	}
	err = cursor.All(context.TODO(), &res)
	if err != nil {
		return nil, err
	}
	var names []string
	for _, r := range res {
		names = append(names, r.ProductName)
	}
	return names, nil
}
type ProductListOpt struct {
	IsOpensource          string
	ContainSharedServices []*template.ServiceInfo
	BasicFacility         string
}
func (c *ProductColl) ListWithOption(opt *ProductListOpt) ([]*template.Product, error) {
	var resp []*template.Product
	query := bson.M{}
	if opt.IsOpensource != "" {
		query["is_opensource"] = stringToBool(opt.IsOpensource)
	}
	if len(opt.ContainSharedServices) > 0 {
		query["shared_services"] = bson.M{"$in": opt.ContainSharedServices}
	}
	if opt.BasicFacility != "" {
		query["product_feature.basic_facility"] = opt.BasicFacility
	}
	cursor, err := c.Collection.Find(context.TODO(), query)
	if err != nil {
		return nil, err
	}
	err = cursor.All(context.TODO(), &resp)
	if err != nil {
		return nil, err
	}
	return resp, nil
}