// permission-seed upserts the platform permission catalog and default system
// roles for one or more tenants. Safe to re-run (idempotent by key).
package main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"strings"
	"time"

	libmongo "gateway/internal/library/mongo"
	permrepo "gateway/internal/model/permission/repository"
	permseed "gateway/internal/model/permission/seed"

	"github.com/zeromicro/go-zero/core/logx"
)

var (
	flagMongoHost = flag.String("mongo-host", envOr("K6_MONGO_HOST", "127.0.0.1"), "Mongo host")
	flagMongoPort = flag.Int("mongo-port", envOrInt("K6_MONGO_PORT", 27017), "Mongo port")
	flagMongoDB   = flag.String("mongo-db", envOr("K6_MONGO_DB", "gateway_k6"), "Mongo database")
	flagTenants   = flag.String("tenants", envOr("PERM_SEED_TENANTS", "k6-tenant"), "Comma-separated tenant_id list")
)

func main() {
	flag.Parse()
	logx.Disable()

	ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
	defer cancel()

	tenantIDs := splitCSV(*flagTenants)
	if len(tenantIDs) == 0 {
		exitf("no tenants to seed")
	}

	conf := &libmongo.Conf{
		Schema:   "mongodb",
		Host:     *flagMongoHost,
		Port:     *flagMongoPort,
		Database: *flagMongoDB,
	}

	perms := permrepo.NewPermissionRepository(permrepo.PermissionRepositoryParam{Conf: conf})
	roles := permrepo.NewRoleRepository(permrepo.RoleRepositoryParam{Conf: conf})
	rolePerms := permrepo.NewRolePermissionRepository(permrepo.RolePermissionRepositoryParam{Conf: conf})

	rpt, err := permseed.Apply(ctx, perms, roles, rolePerms, permseed.ApplyOptions{
		TenantIDs: tenantIDs,
	})
	if err != nil {
		exitf("seed: %v", err)
	}

	logf("tenants=%v catalog=%d roles=%d role_perms=%d",
		tenantIDs, rpt.CatalogUpserted, rpt.RolesUpserted, rpt.RolePermissionSet)
}

func splitCSV(s string) []string {
	parts := strings.Split(s, ",")
	out := make([]string, 0, len(parts))
	for _, p := range parts {
		p = strings.TrimSpace(p)
		if p != "" {
			out = append(out, p)
		}
	}
	return out
}

func envOr(k, def string) string {
	if v := os.Getenv(k); v != "" {
		return v
	}
	return def
}

func envOrInt(k string, def int) int {
	if v := os.Getenv(k); v != "" {
		var n int
		if _, err := fmt.Sscanf(v, "%d", &n); err == nil {
			return n
		}
	}
	return def
}

func logf(format string, a ...any) {
	fmt.Fprintf(os.Stderr, "[permission-seed] "+format+"\n", a...)
}

func exitf(format string, a ...any) {
	logf(format, a...)
	os.Exit(1)
}
