// The skeleton command prints the boilerplate for a concrete type
// that implements the specified interface type.
//
// Example:
//
//	$ ./skeleton io ReadWriteCloser buffer
//	// *buffer implements io.ReadWriteCloser.
//	type buffer struct{ /* ... */ }
//	func (b *buffer) Close() error { panic("unimplemented") }
//	func (b *buffer) Read(p []byte) (n int, err error) { panic("unimplemented") }
//	func (b *buffer) Write(p []byte) (n int, err error) { panic("unimplemented") }
package main

import (
	"fmt"
	"go/types"
	"log"
	"os"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/tools/go/packages"
)

const usage = "Usage: skeleton <package> <interface> <concrete>"

// !+
func PrintSkeleton(pkg *types.Package, ifacename, concname string) error {
	obj := pkg.Scope().Lookup(ifacename)
	if obj == nil {
		return fmt.Errorf("%s.%s not found", pkg.Path(), ifacename)
	}
	if _, ok := obj.(*types.TypeName); !ok {
		return fmt.Errorf("%v is not a named type", obj)
	}
	iface, ok := obj.Type().Underlying().(*types.Interface)
	if !ok {
		return fmt.Errorf("type %v is a %T, not an interface",
			obj, obj.Type().Underlying())
	}
	// Use first letter of type name as receiver parameter.
	if !isValidIdentifier(concname) {
		return fmt.Errorf("invalid concrete type name: %q", concname)
	}
	r, _ := utf8.DecodeRuneInString(concname)

	fmt.Printf("// *%s implements %s.%s.\n", concname, pkg.Path(), ifacename)
	fmt.Printf("type %s struct{}\n", concname)
	mset := types.NewMethodSet(iface)
	for i := 0; i < mset.Len(); i++ {
		meth := mset.At(i).Obj()
		sig := types.TypeString(meth.Type(), (*types.Package).Name)
		fmt.Printf("func (%c *%s) %s%s {\n\tpanic(\"unimplemented\")\n}\n",
			r, concname, meth.Name(),
			strings.TrimPrefix(sig, "func"))
	}
	return nil
}

//!-

func isValidIdentifier(id string) bool {
	for i, r := range id {
		if !unicode.IsLetter(r) &&
			!(i > 0 && unicode.IsDigit(r)) {
			return false
		}
	}
	return id != ""
}

func main() {
	if len(os.Args) != 4 {
		log.Fatal(usage)
	}
	pkgpath, ifacename, concname := os.Args[1], os.Args[2], os.Args[3]

	// Load only exported type information for the specified package.
	conf := &packages.Config{Mode: packages.NeedTypes}
	pkgs, err := packages.Load(conf, pkgpath)
	if err != nil {
		log.Fatal(err) // failed to load anything
	}
	if packages.PrintErrors(pkgs) > 0 {
		os.Exit(1) // some packages contained errors
	}
	if err := PrintSkeleton(pkgs[0].Types, ifacename, concname); err != nil {
		log.Fatal(err)
	}
}

/*
//!+output1
$ ./skeleton io ReadWriteCloser buffer
// *buffer implements io.ReadWriteCloser.
type buffer struct{}
func (b *buffer) Close() error {
	panic("unimplemented")
}
func (b *buffer) Read(p []byte) (n int, err error) {
	panic("unimplemented")
}
func (b *buffer) Write(p []byte) (n int, err error) {
	panic("unimplemented")
}
//!-output1

//!+output2
$ ./skeleton net/http Handler myHandler
// *myHandler implements net/http.Handler.
type myHandler struct{}
func (m *myHandler) ServeHTTP(http.ResponseWriter, *http.Request) {
	panic("unimplemented")
}
//!-output2
*/
