package main

import (
	"strings"

	"google.golang.org/protobuf/compiler/protogen"
)

func generateGRPC(gen *protogen.Plugin) {
	g := gen.NewGeneratedFile("grpc/grpc.sdk.gen.go", importPath+"/grpc")
	g.P("// Code generated by protoc-gen-go-flipt-sdk. DO NOT EDIT.")
	g.P()
	g.P("package grpc")
	g.P()

	sdk := importPackage(g, importPath)
	g.P("var _ ", sdk("Transport"), " = Transport{}")

	g.P("type Transport struct {")
	grpc := importPackage(g, "google.golang.org/grpc")
	g.P("cc ", grpc("ClientConnInterface"))
	g.P("}\n")

	g.P("func NewTransport(cc ", grpc("ClientConnInterface"), ") Transport {")
	g.P("return Transport{cc: cc}")
	g.P("}\n")

	for _, file := range gen.Files {
		if !file.Generate {
			continue
		}

		var (
			typ    = strings.Title(string(file.GoPackageName))
			method = typ + "Client"
		)

		if len(file.Services) == 1 {
			returnType := file.Services[0].GoName + "Client"
			g.P("func (t Transport) ", method, "() ", relativeImport(g, file, returnType), "{")
			g.P("return ", relativeImport(g, file, "New"+returnType), "(t.cc)")
			g.P("}\n")
			continue
		}

		// the following handles bundling together packages containing more than
		// one service definition into a single unexported type which implements
		// the combined client interface the SDK generator produces.
		groupType := unexport(method)
		g.P("type ", groupType, " struct {")
		g.P("cc ", grpc("ClientConnInterface"))
		g.P("}\n")

		for _, srv := range file.Services {
			returnType := srv.GoName + "Client"
			g.P("func (t ", groupType, ") ", returnType, "() ", relativeImport(g, file, returnType), " {")
			g.P("return ", relativeImport(g, file, "New"+returnType), "(t.cc)")
			g.P("}\n")
		}

		g.P("func (t Transport) ", method, "() ", sdk(method), "{")
		g.P("return ", groupType, "{cc: t.cc}")
		g.P("}\n")
	}
}
