// Copyright 2023 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// protoveneer generates idiomatic Go types that correspond to protocol
// buffer messages and enums -- a veneer on top of the proto layer.
//
// # Relationship to GAPICs
//
// GAPICs and this tool complement each other.
//
// GAPICs have client types and idiomatic methods on them that correspond to
// RPCs. They focus on the RPC part of a service. A GAPIC relies on the
// underlying protocol buffer types for the request and response types, and all
// the types that these refer to.
//
// protoveener generates Go types that correspond to proto messages and enums,
// including requests and responses if desired. It doesn't touch the RPC parts
// of the proto definition.
//
// # Configuration
//
// protoveneer requires significant configuration to produce good results.
// See the config type in config.go and the config.yaml files in the testdata
// subdirectories to understand how to write configuration.
//
// # Support functions
//
// protoveneer generates code that relies on a few support functions. These live
// in the support subdirectory. You should copy the contents of this directory
// to a location of your choice, and add "supportImportPath" to your config to
// refer to that directory's import path.
//
// # Unhandled features
//
// There is no support for oneofs. Omit the oneof type and write custom code.
// However, the types of the individual oneof cases can be generated.
package main

// TODO:
// - have omitFields on a TypeConfig, like omitTypes
// - Instead of parseCustomConverter, accept a list. Users can use the inline form
//   to be compact.
// - Check that a configured field is actually in the type.

import (
	"bytes"
	"context"
	"errors"
	"flag"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io"
	"log"
	"os"
	"path"
	"path/filepath"
	"sort"
	"strings"
	"text/template"
	"time"
	"unicode"
)

var (
	outputDir = flag.String("outdir", "", "directory to write to, or '-' for stdout")
	noFormat  = flag.Bool("nofmt", false, "do not format output")
)

func main() {
	log.SetPrefix("protoveneer: ")
	log.SetFlags(0)
	flag.Usage = func() {
		out := flag.CommandLine.Output()
		fmt.Fprintf(out, "usage: protoveneer CONFIG.yaml DIR_WITH_pb.go_FILES\n")
		flag.PrintDefaults()
	}
	flag.Parse()

	if err := run(context.Background(), flag.Arg(0), flag.Arg(1), *outputDir); err != nil {
		log.Fatal(err)
	}
}

func run(ctx context.Context, configFile, pbDir, outDir string) error {
	config, err := readConfigFile(configFile)
	if err != nil {
		return err
	}

	fset := token.NewFileSet()
	pkg, err := parseDir(fset, pbDir)
	if err != nil {
		return err
	}

	src, err := generate(config, pkg, fset)
	if err != nil {
		return err
	}
	if !*noFormat {
		src, err = format.Source(src)
		if err != nil {
			return err
		}
	}

	if outDir == "-" {
		fmt.Printf("%s\n", src)
	} else {
		outfile := fmt.Sprintf("%s_veneer.gen.go", pkg.Name)
		if outDir != "" {
			outfile = filepath.Join(outDir, outfile)
		}
		if err := os.WriteFile(outfile, src, 0660); err != nil {
			log.Fatal(err)
		}
		fmt.Printf("wrote %s\n", outfile)
	}
	return nil
}

func parseDir(fset *token.FileSet, dir string) (*ast.Package, error) {
	pkgs, err := parser.ParseDir(fset, dir, nil, parser.ParseComments)
	if err != nil {
		return nil, err
	}
	if len(pkgs) > 2 {
		return nil, errors.New("too many packages")
	}
	var pkg *ast.Package
	for name, apkg := range pkgs {
		if !strings.HasSuffix(name, "_test") {
			pkg = apkg
			break
		}
	}
	if pkg == nil {
		return nil, errors.New("no non-test package")
	}
	for filename := range pkg.Files {
		if !strings.HasSuffix(filename, ".pb.go") {
			return nil, fmt.Errorf("%s is not a .pb.go file", filename)
		}
	}
	return pkg, nil
}

func generate(conf *config, pkg *ast.Package, fset *token.FileSet) (src []byte, err error) {
	// Get information about all the types in the proto package.
	typeInfos, err := collectDecls(pkg)
	if err != nil {
		return nil, err
	}

	// Check that every configured type is present.
	for protoName := range conf.Types {
		if typeInfos[protoName] == nil {
			return nil, fmt.Errorf("configured type %s does not exist in package", protoName)
		}
	}

	// Consult the config to determine which types to omit.
	// If a type isn't matched by a glob in the OmitTypes list, it is output.
	// If a type is matched, but it also has a config, it is still output.
	var toWrite []*typeInfo
	for name, ti := range typeInfos {
		if !ast.IsExported(name) {
			continue
		}
		omit, err := sliceAnyError(conf.OmitTypes, func(glob string) (bool, error) {
			return path.Match(glob, name)
		})
		if err != nil {
			return nil, err
		}
		if !omit || conf.Types[name] != nil {
			toWrite = append(toWrite, ti)
		}
	}

	// Fill in the configured type names, which we need to do the rest of the work.
	for _, ti := range toWrite {
		if tc := conf.Types[ti.protoName]; tc != nil && tc.Name != "" {
			ti.veneerName = tc.Name
		}
	}

	// Sort for determinism.
	sort.Slice(toWrite, func(i, j int) bool {
		return toWrite[i].veneerName < toWrite[j].veneerName
	})

	// Process and configure all the types we care about.
	// Even if there is no config for a type, there is still work to do.
	for _, ti := range toWrite {
		if err := processType(ti, conf.Types[ti.protoName], typeInfos); err != nil {
			return nil, err
		}
	}

	converters, err := buildConverterMap(toWrite, conf)
	if err != nil {
		return nil, err
	}

	// Use the converters map to give every field a converter.
	for _, ti := range toWrite {
		for _, f := range ti.fields {
			f.converter, err = makeConverter(f.af.Type, f.protoType, converters)
			if err != nil {
				return nil, fmt.Errorf("%s.%s: %w", ti.protoName, f.protoName, err)
			}
		}
	}

	// Write the generated code.
	return write(toWrite, conf, fset)
}

// buildConverterMap builds a map from veneer name to a converter, which writes code that converts between the proto and veneer.
// This is used for fields when generating conversion functions.
func buildConverterMap(typeInfos []*typeInfo, conf *config) (map[string]converter, error) {
	converters := map[string]converter{}
	// Build a converter for each proto type.
	for _, ti := range typeInfos {
		var conv converter
		// Custom converters on the type take precedence.
		if tc := conf.Types[ti.protoName]; tc != nil && tc.ConvertToFrom != "" {
			c, err := parseCustomConverter(ti.veneerName, tc.ConvertToFrom)
			if err != nil {
				return nil, err
			}
			conv = c
		} else {
			switch ti.spec.Type.(type) {
			case *ast.StructType:
				conv = protoConverter{veneerName: ti.veneerName}
			case *ast.Ident:
				conv = enumConverter{protoName: ti.protoName, veneerName: ti.veneerName}
			default:
				conv = identityConverter{}
			}
		}
		converters[ti.veneerName] = conv
	}

	// Add converters for used external types to the map.
	for _, et := range externalTypes {
		if et.used {
			converters[et.qualifiedName] = customConverter{et.convertTo, et.convertFrom}
		}
	}

	// Add custom converters to the map.
	// These differ from custom converters on the proto types (a few lines above here)
	// because they are keyed by veneer type, not proto type.
	// That can matter when the proto type is omitted but there is a corresponding
	// veneer type.
	for key, value := range conf.Converters {
		c, err := parseCustomConverter(key, value)
		if err != nil {
			return nil, err
		}
		converters[key] = c
	}
	return converters, nil
}

func parseCustomConverter(name, value string) (converter, error) {
	toFunc, fromFunc, ok := strings.Cut(value, ",")
	toFunc = strings.TrimSpace(toFunc)
	fromFunc = strings.TrimSpace(fromFunc)
	if !ok || toFunc == "" || fromFunc == "" {
		return nil, fmt.Errorf(`%s: ConvertToFrom = %q, want "toFunc, fromFunc"`, name, value)
	}
	return customConverter{toFunc, fromFunc}, nil
}

// makeConverter constructs a converter for the given type. Not every type is in the map: this
// function puts together converters for types like pointers, slices and maps, as well as
// named types.
func makeConverter(veneerType, protoType ast.Expr, converters map[string]converter) (converter, error) {
	if c, ok := converters[typeString(veneerType)]; ok {
		return c, nil
	}
	// If there is no converter for this type, look for a converter for a part of the type.
	switch t := veneerType.(type) {
	case *ast.Ident:
		// Handle the case where the veneer type is the dereference of the proto type.
		if se, ok := protoType.(*ast.StarExpr); ok {
			if identName(se.X) != t.Name {
				return nil, fmt.Errorf("veneer type %s does not match dereferenced proto type %s", t.Name, identName(se.X))
			}
			return derefConverter{}, nil
		}
		return identityConverter{}, nil
	case *ast.StarExpr:
		return makeConverter(t.X, protoType.(*ast.StarExpr).X, converters)
	case *ast.ArrayType:
		eltc, err := makeConverter(t.Elt, protoType.(*ast.ArrayType).Elt, converters)
		if err != nil {
			return nil, err
		}
		return sliceConverter{eltc}, nil
	case *ast.MapType:
		// Assume the key types are the same.
		vc, err := makeConverter(t.Value, protoType.(*ast.MapType).Value, converters)
		if err != nil {
			return nil, err
		}
		return mapConverter{vc}, nil
	default:
		return identityConverter{}, nil
	}
}

// A typeInfo holds information about a named type.
type typeInfo struct {
	// These fields are collected from the proto package.
	protoName string        // name of type in the proto package
	spec      *ast.TypeSpec // the spec for the type, which will be modified
	decl      *ast.GenDecl  // the decl holding the spec; not sure we need this
	values    *ast.GenDecl  // the list of values for an enum

	// These fields are added later.
	veneerName string       // may be provided by config; else same as protoName
	fields     []*fieldInfo // for structs
	valueNames []string     // to generate String functions
}

// A fieldInfo holds information about a struct field.
type fieldInfo struct {
	protoType             ast.Expr
	af                    *ast.Field
	protoName, veneerName string
	converter             converter
}

// collectDecls collects declaration information from a package.
// It returns information about every named type in the package in a map
// keyed by the type's name.
func collectDecls(pkg *ast.Package) (map[string]*typeInfo, error) {
	typeInfos := map[string]*typeInfo{} // key is proto name

	getInfo := func(name string) *typeInfo {
		if info, ok := typeInfos[name]; ok {
			return info
		}
		info := &typeInfo{protoName: name, veneerName: name}
		typeInfos[name] = info
		return info
	}

	for _, file := range pkg.Files {
		for _, decl := range file.Decls {
			if gd, ok := decl.(*ast.GenDecl); ok {
				switch gd.Tok {
				case token.TYPE:
					if len(gd.Specs) != 1 {
						return nil, errors.New("multiple TypeSpecs in a GenDecl not supported")
					}
					ts := gd.Specs[0].(*ast.TypeSpec)
					info := getInfo(ts.Name.Name)
					info.spec = ts
					info.decl = gd

				case token.CONST:
					// Assume consts for an enum type are grouped together, and every one has a type.
					// That's what the proto compiler generates.
					vs0 := gd.Specs[0].(*ast.ValueSpec)
					if len(vs0.Names) != 1 || len(vs0.Values) != 1 {
						return nil, errors.New("multiple names/values not supported")
					}

					protoName := identName(vs0.Type)
					if protoName == "" {
						continue
					}
					for _, s := range gd.Specs {
						vs := s.(*ast.ValueSpec)
						if identName(vs.Type) != protoName {
							return nil, fmt.Errorf("%s: not all same type", protoName)
						}
					}
					info := getInfo(protoName)
					info.values = gd
				}
			}
		}
	}
	return typeInfos, nil
}

// processType processes a single type, modifying the AST.
// If it's an enum, just change its name.
// If it's a struct, modify its name and fields.
func processType(ti *typeInfo, tconf *typeConfig, typeInfos map[string]*typeInfo) error {
	ti.spec.Name.Name = ti.veneerName
	switch t := ti.spec.Type.(type) {
	case *ast.StructType:
		// Check that all configured fields are present.
		exportedFields := map[string]bool{}
		for _, f := range t.Fields.List {
			if len(f.Names) > 1 {
				return fmt.Errorf("%s: multiple names in one field spec not supported: %v", ti.protoName, f.Names)
			}
			if f.Names[0].IsExported() {
				exportedFields[f.Names[0].Name] = true
			}
		}
		if tconf != nil {
			for name := range tconf.Fields {
				if !exportedFields[name] {
					return fmt.Errorf("%s: configured field %s is not present", ti.protoName, name)
				}
			}
		}
		// Process the fields.
		fs := t.Fields.List
		t.Fields.List = t.Fields.List[:0]
		for _, f := range fs {
			fi, err := processField(f, tconf, typeInfos)
			if err != nil {
				return err
			}
			if fi != nil {
				t.Fields.List = append(t.Fields.List, f)
				ti.fields = append(ti.fields, fi)
			}
		}
	case *ast.Ident:
		// Enum type. Nothing else to do with the type itself; but see processEnumValues.
	default:
		return fmt.Errorf("unknown type: %+v: protoName=%s", ti.spec, ti.protoName)
	}
	processDoc(ti.decl, ti.protoName, tconf)
	if ti.values != nil {
		ti.valueNames = processEnumValues(ti.values, tconf)
	}
	return nil
}

// processField processes a struct field.
func processField(af *ast.Field, tc *typeConfig, typeInfos map[string]*typeInfo) (*fieldInfo, error) {
	id := af.Names[0]
	if !id.IsExported() {
		return nil, nil
	}
	fi := &fieldInfo{
		protoType:  af.Type,
		af:         af,
		protoName:  id.Name,
		veneerName: id.Name,
	}
	if tc != nil {
		if fc, ok := tc.Fields[id.Name]; ok {
			if fc.Omit {
				return nil, nil
			}
			if fc.Name != "" {
				id.Name = fc.Name
				fi.veneerName = fc.Name
			}
			if fc.Type != "" {
				expr, err := parser.ParseExpr(fc.Type)
				if err != nil {
					return nil, err
				}
				af.Type = expr
			}
		}
	}
	af.Type = veneerType(af.Type, typeInfos)
	af.Tag = nil
	return fi, nil
}

// veneerType returns a type expression for the veneer type corresponding to the given proto type.
func veneerType(protoType ast.Expr, typeInfos map[string]*typeInfo) ast.Expr {
	var wtype func(ast.Expr) ast.Expr
	wtype = func(protoType ast.Expr) ast.Expr {
		if et := protoTypeToExternalType[typeString(protoType)]; et != nil {
			et.used = true
			return et.typeExpr
		}
		switch t := protoType.(type) {
		case *ast.Ident:
			if ti := typeInfos[t.Name]; ti != nil {
				wt := *t
				wt.Name = ti.veneerName
				return &wt
			}
		case *ast.ParenExpr:
			wt := *t
			wt.X = wtype(wt.X)
			return &wt

		case *ast.StarExpr:
			wt := *t
			wt.X = wtype(wt.X)
			return &wt

		case *ast.ArrayType:
			wt := *t
			wt.Elt = wtype(wt.Elt)
			return &wt
		}
		return protoType
	}

	return wtype(protoType)
}

// processEnumValues processes enum values.
// The proto compiler puts all the values for an enum in one GenDecl,
// and there are no other values in that GenDecl.
func processEnumValues(d *ast.GenDecl, tc *typeConfig) []string {
	var valueNames []string
	for _, s := range d.Specs {
		vs := s.(*ast.ValueSpec)
		id := vs.Names[0]
		protoName := id.Name
		veneerName := veneerValueName(id.Name, tc)
		valueNames = append(valueNames, veneerName)
		id.Name = veneerName

		if tc != nil {
			vs.Type.(*ast.Ident).Name = tc.Name
		}
		modifyCommentGroup(vs.Doc, protoName, veneerName, "means", "")
	}
	return valueNames
}

// veneerValueName returns an idiomatic Go name for a proto enum value.
func veneerValueName(protoValueName string, tc *typeConfig) string {
	if tc == nil {
		return protoValueName
	}
	if nn, ok := tc.ValueNames[protoValueName]; ok {
		return nn
	}
	name := strings.TrimPrefix(protoValueName, tc.ProtoPrefix)
	// Some values have the type name in upper snake case after the prefix.
	// Example:
	//    proto type: FinishReason
	//    prefix: Candidate_
	//    value:  Candidate_FINISH_REASON_UNSPECIFIED
	prefix := camelToUpperSnakeCase(tc.Name) + "_"
	name = strings.TrimPrefix(name, prefix)
	return tc.VeneerPrefix + snakeToCamelCase(name)
}

func processDoc(gd *ast.GenDecl, protoName string, tc *typeConfig) {
	doc := ""
	verb := ""
	if tc != nil {
		doc = tc.Doc
		verb = tc.DocVerb
	}

	spec := gd.Specs[0]
	var name string
	switch spec := spec.(type) {
	case *ast.TypeSpec:
		name = spec.Name.Name
	case *ast.ValueSpec:
		name = spec.Names[0].Name
	default:
		panic("bad spec")
	}
	if tc != nil && name != tc.Name {
		panic(fmt.Errorf("GenDecl name is %q, config name is %q", name, tc.Name))
	}
	modifyCommentGroup(gd.Doc, protoName, name, verb, doc)
}

func modifyCommentGroup(cg *ast.CommentGroup, protoName, veneerName, verb, doc string) {
	if cg == nil {
		return
	}
	if len(cg.List) == 0 {
		return
	}
	c := cg.List[0]
	c.Text = "// " + adjustDoc(strings.TrimPrefix(c.Text, "// "), protoName, veneerName, verb, doc)
}

// adjustDoc takes a doc string with initial comment characters and whitespace removed, and returns
// a replacement that uses the given veneer name, verb and new doc string.
func adjustDoc(origDoc, protoName, veneerName, verb, newDoc string) string {
	// if newDoc is non-empty, completely replace the existing doc.
	if newDoc != "" {
		return veneerName + " " + newDoc
	}
	// If the doc string starts with the proto name, just replace it with the
	// veneer name. We can't do anything about the verb because we don't know
	// where it is in the original doc string. (I guess we could assume it's the
	// next word, but that might not always work.)
	if strings.HasPrefix(origDoc, protoName+" ") {
		return veneerName + origDoc[len(protoName):]
	}

	// Lowercase the first letter of the given doc if it's not part of an acronym.
	runes := []rune(origDoc)
	// It shouldn't be possible for the original doc string to be empty,
	// but check just in case to avoid panics.
	if len(runes) == 0 {
		return origDoc
	}
	// Heuristic: an acronym begins with two consecutive uppercase letters.
	if unicode.IsUpper(runes[0]) && (len(runes) == 1 || !unicode.IsUpper(runes[1])) {
		runes[0] = unicode.ToLower(runes[0])
		origDoc = string(runes)
	}

	if verb == "" {
		verb = "is"
	}
	return fmt.Sprintf("%s %s %s", veneerName, verb, origDoc)
}

////////////////////////////////////////////////////////////////

const licenseFormat = `// Copyright %d Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`

func write(typeInfos []*typeInfo, conf *config, fset *token.FileSet) ([]byte, error) {
	var buf bytes.Buffer
	pr := func(format string, args ...any) { fmt.Fprintf(&buf, format, args...) }
	prn := func(format string, args ...any) {
		pr(format, args...)
		pr("\n")
	}
	// Top of file.
	pr(licenseFormat, time.Now().Year())
	prn("")
	pr("// This file was generated by protoveneer. DO NOT EDIT.\n\n")
	pr("package %s\n\n", conf.Package)
	prn("import (")
	prn(`    "fmt"`)
	pr("\n")
	prn(`    pb "%s"`, conf.ProtoImportPath)
	if conf.SupportImportPath == "" {
		return nil, errors.New("missing supportImportPath in config")
	}
	prn(`    "%s"`, conf.SupportImportPath)
	for _, et := range externalTypes {
		if et.used && et.importPath != "" {
			prn(`    "%s"`, et.importPath)
		}
	}
	pr(")\n\n")

	// Types.
	for _, ti := range typeInfos {
		for _, decl := range []*ast.GenDecl{ti.decl, ti.values} {
			if decl != nil {
				data, err := formatDecl(fset, decl)
				if err != nil {
					return nil, err
				}
				buf.Write(data)
				prn("")
			}
		}
		if ti.valueNames != nil {
			if err := generateEnumStringMethod(&buf, ti.veneerName, ti.valueNames); err != nil {
				return nil, err
			}
		}
		if _, ok := ti.spec.Type.(*ast.StructType); ok {
			ti.generateConversionMethods(pr)
		}
	}

	return buf.Bytes(), nil
}

func formatDecl(fset *token.FileSet, gd *ast.GenDecl) ([]byte, error) {
	var buf bytes.Buffer
	if err := format.Node(&buf, fset, gd); err != nil {
		return nil, err
	}
	// Remove blank lines that result from deleting unexported struct fields.
	return bytes.ReplaceAll(buf.Bytes(), []byte("\n\n"), []byte("\n")), nil
}

////////////////////////////////////////////////////////////////

var stringMethodTemplate = template.Must(template.New("").Parse(`
	var namesFor{{.Type}} = map[{{.Type}}]string {
		{{- range .Values}}
			{{.}}: "{{.}}",
		{{- end}}
	}

	func (v {{.Type}}) String() string {
		if n, ok := namesFor{{.Type}}[v]; ok {
			return n
		}
		return fmt.Sprintf("{{.Type}}(%d)", v)
	}
`))

func generateEnumStringMethod(w io.Writer, typeName string, valueNames []string) error {
	return stringMethodTemplate.Execute(w, struct {
		Type   string
		Values []string
	}{typeName, valueNames})
}

func (ti *typeInfo) generateConversionMethods(pr func(string, ...any)) {
	ti.generateToProto(pr)
	pr("\n")
	ti.generateFromProto(pr)
}

func (ti *typeInfo) generateToProto(pr func(string, ...any)) {
	pr("func (v *%s) toProto() *pb.%s {\n", ti.veneerName, ti.protoName)
	pr("  if v == nil { return nil }\n")
	pr("  return &pb.%s{\n", ti.protoName)
	for _, f := range ti.fields {
		pr("        %s: %s,\n", f.protoName, f.converter.genTo("v."+f.veneerName))
	}
	pr("    }\n")
	pr("}\n")
}

func (ti *typeInfo) generateFromProto(pr func(string, ...any)) {
	pr("func (%s) fromProto(p *pb.%s) *%[1]s {\n", ti.veneerName, ti.protoName)
	pr("  if p == nil { return nil }\n")
	pr("  return &%s{\n", ti.veneerName)
	for _, f := range ti.fields {
		pr("        %s: %s,\n", f.veneerName, f.converter.genFrom("p."+f.protoName))
	}
	pr("    }\n")
	pr("}\n")
}

////////////////////////////////////////////////////////////////

// externalType holds information about a type that is not part of the proto package.
type externalType struct {
	qualifiedName string
	replaces      string
	importPath    string
	convertTo     string
	convertFrom   string

	typeExpr ast.Expr
	used     bool
}

var externalTypes = []*externalType{
	{
		qualifiedName: "civil.Date",
		replaces:      "*date.Date",
		importPath:    "cloud.google.com/go/civil",
		convertTo:     "support.CivilDateToProto",
		convertFrom:   "support.CivilDateFromProto",
	},
	{
		qualifiedName: "map[string]any",
		replaces:      "*structpb.Struct",
		convertTo:     "support.MapToStructPB",
		convertFrom:   "support.MapFromStructPB",
	},
}

var protoTypeToExternalType = map[string]*externalType{}

func init() {
	var err error
	for _, et := range externalTypes {
		et.typeExpr, err = parser.ParseExpr(et.qualifiedName)
		if err != nil {
			panic(err)
		}
		protoTypeToExternalType[et.replaces] = et
	}
}

////////////////////////////////////////////////////////////////

var emptyFileSet = token.NewFileSet()

// typeString produces a string for a type expression.
func typeString(t ast.Expr) string {
	var buf bytes.Buffer
	err := format.Node(&buf, emptyFileSet, t)
	if err != nil {
		panic(err)
	}
	return buf.String()
}

func identName(x any) string {
	id, ok := x.(*ast.Ident)
	if !ok {
		return ""
	}
	return id.Name
}

func snakeToCamelCase(s string) string {
	words := strings.Split(s, "_")
	for i, w := range words {
		if len(w) == 0 {
			words[i] = w
		} else {
			words[i] = fmt.Sprintf("%c%s", unicode.ToUpper(rune(w[0])), strings.ToLower(w[1:]))
		}
	}
	return strings.Join(words, "")
}

func camelToUpperSnakeCase(s string) string {
	var res []rune
	for i, r := range s {
		if unicode.IsUpper(r) && i > 0 {
			res = append(res, '_')
		}
		res = append(res, unicode.ToUpper(r))
	}
	return string(res)
}

func sliceAnyError[T any](s []T, f func(T) (bool, error)) (bool, error) {
	for _, e := range s {
		b, err := f(e)
		if err != nil {
			return false, err
		}
		if b {
			return true, nil
		}
	}
	return false, nil
}
