package main

import (
	"fmt"
	"os"
	"path/filepath"
	"text/template"
)

const permsTpl = `// Code generated by permgen. DO NOT EDIT.

package perms

import "code.clickto.dev/weiym/permlib"

// Perms 权限声明列表，启动时调用 engine.RegisterPerms(Perms) 同步到权限系统
var Perms = []permlib.PermDecl{
{{- range .Perms}}
	{Code: {{printf "%q" .Code}}, Name: {{printf "%q" .Name}}},
{{- end}}
}

// RoutePerms 路由-权限映射，启动时调用 engine.RegisterRoutePerms(RoutePerms)
var RoutePerms = []permlib.RoutePermDecl{
{{- range .RoutePerms}}
	{Method: {{printf "%q" .Method}}, Path: {{printf "%q" .Path}}, PermCode: {{printf "%q" .PermCode}}, DataCode: {{printf "%q" .DataCode}}},
{{- end}}
}

// FieldPerms 字段权限映射，启动时调用 engine.RegisterFieldPerms(FieldPerms)
var FieldPerms = map[string]permlib.FieldPermMap{
{{- range $key, $fm := .FieldPerms}}
	{{printf "%q" $key}}: {
		{{- if $fm.Request}}
		Request: map[string]string{
			{{- range $field, $code := $fm.Request}}
			{{printf "%q" $field}}: {{printf "%q" $code}},
			{{- end}}
		},
		{{- end}}
		{{- if $fm.Response}}
		Response: map[string]string{
			{{- range $field, $code := $fm.Response}}
			{{printf "%q" $field}}: {{printf "%q" $code}},
			{{- end}}
		},
		{{- end}}
	},
{{- end}}
}
`

type templateData struct {
	Perms      []permDecl
	RoutePerms []routePermDecl
	FieldPerms map[string]fieldPermMap
}

func generate(result *collectResult, dir string) error {
	outDir := filepath.Join(dir, "internal", "perms")
	if err := os.MkdirAll(outDir, 0755); err != nil {
		return fmt.Errorf("创建目录失败: %w", err)
	}

	outFile := filepath.Join(outDir, "perms.go")

	tpl, err := template.New("perms").Funcs(template.FuncMap{
		"printf": fmt.Sprintf,
	}).Parse(permsTpl)
	if err != nil {
		return fmt.Errorf("解析模板失败: %w", err)
	}

	f, err := os.Create(outFile)
	if err != nil {
		return fmt.Errorf("创建文件失败: %w", err)
	}
	defer f.Close()

	data := templateData{
		Perms:      result.perms,
		RoutePerms: result.routePerms,
		FieldPerms: result.fieldPerms,
	}

	if err := tpl.Execute(f, data); err != nil {
		return fmt.Errorf("生成文件失败: %w", err)
	}

	fmt.Fprintf(os.Stdout, "permgen: generated %s (%d perms, %d routes, %d field maps)\n",
		outFile,
		len(result.perms),
		len(result.routePerms),
		len(result.fieldPerms),
	)
	return nil
}

