// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"
	"unicode"

	"google.golang.org/api/google-api-go-generator/internal/disco"
)

const (
	googleDiscoveryURL = "https://www.googleapis.com/discovery/v1/apis"
	generatorVersion   = "2018018"
)

var (
	apiToGenerate = flag.String("api", "*", "The API ID to generate, like 'tasks:v1'. A value of '*' means all.")
	useCache      = flag.Bool("cache", true, "Use cache of discovered Google API discovery documents.")
	genDir        = flag.String("gendir", "", "Directory to use to write out generated Go files")
	build         = flag.Bool("build", false, "Compile generated packages.")
	install       = flag.Bool("install", false, "Install generated packages.")
	apisURL       = flag.String("discoveryurl", googleDiscoveryURL, "URL to root discovery document")

	publicOnly = flag.Bool("publiconly", true, "Only build public, released APIs. Only applicable for Google employees.")

	jsonFile       = flag.String("api_json_file", "", "If non-empty, the path to a local file on disk containing the API to generate. Exclusive with setting --api.")
	output         = flag.String("output", "", "(optional) Path to source output file. If not specified, the API name and version are used to construct an output path (e.g. tasks/v1).")
	apiPackageBase = flag.String("api_pkg_base", "google.golang.org/api", "Go package prefix to use for all generated APIs.")
	baseURL        = flag.String("base_url", "", "(optional) Override the default service API URL. If empty, the service's root URL will be used.")
	headerPath     = flag.String("header_path", "", "If non-empty, prepend the contents of this file to generated services.")

	gensupportPkg = flag.String("gensupport_pkg", "google.golang.org/api/gensupport", "Go package path of the 'api/gensupport' support package.")
	googleapiPkg  = flag.String("googleapi_pkg", "google.golang.org/api/googleapi", "Go package path of the 'api/googleapi' support package.")

	serviceTypes = []string{"Service", "APIService"}
)

// API represents an API to generate, as well as its state while it's
// generating.
type API struct {
	// Fields needed before generating code, to select and find the APIs
	// to generate.
	// These fields usually come from the "directory item" JSON objects
	// that are provided by the googleDiscoveryURL. We unmarshal a directory
	// item directly into this struct.
	ID            string `json:"id"`
	Name          string `json:"name"`
	Version       string `json:"version"`
	DiscoveryLink string `json:"discoveryRestUrl"` // absolute

	doc *disco.Document
	// TODO(jba): remove m when we've fully converted to using disco.
	m map[string]interface{}

	forceJSON     []byte // if non-nil, the JSON schema file. else fetched.
	usedNames     namePool
	schemas       map[string]*Schema // apiName -> schema
	responseTypes map[string]bool

	p  func(format string, args ...interface{}) // print raw
	pn func(format string, args ...interface{}) // print with newline
}

func (a *API) sortedSchemaNames() (names []string) {
	for name := range a.schemas {
		names = append(names, name)
	}
	sort.Strings(names)
	return
}

func (a *API) Schema(name string) *Schema {
	return a.schemas[name]
}

type generateError struct {
	api   *API
	error error
}

func (e *generateError) Error() string {
	return fmt.Sprintf("API %s failed to generate code: %v", e.api.ID, e.error)
}

type compileError struct {
	api    *API
	output string
}

func (e *compileError) Error() string {
	return fmt.Sprintf("API %s failed to compile:\n%v", e.api.ID, e.output)
}

func main() {
	flag.Parse()

	if *install {
		*build = true
	}

	var (
		apiIds  = []string{}
		matches = []*API{}
		errors  = []error{}
	)
	for _, api := range getAPIs() {
		apiIds = append(apiIds, api.ID)
		if !api.want() {
			continue
		}
		matches = append(matches, api)
		log.Printf("Generating API %s", api.ID)
		err := api.WriteGeneratedCode()
		if err != nil && err != errNoDoc {
			errors = append(errors, &generateError{api, err})
			continue
		}
		if *build && err == nil {
			var args []string
			if *install {
				args = append(args, "install")
			} else {
				args = append(args, "build")
			}
			args = append(args, api.Target())
			out, err := exec.Command("go", args...).CombinedOutput()
			if err != nil {
				errors = append(errors, &compileError{api, string(out)})
			}
		}
	}

	if len(matches) == 0 {
		log.Fatalf("No APIs matched %q; options are %v", *apiToGenerate, apiIds)
	}

	if len(errors) > 0 {
		log.Printf("%d API(s) failed to generate or compile:", len(errors))
		for _, ce := range errors {
			log.Println(ce.Error())
		}
		os.Exit(1)
	}
}

func (a *API) want() bool {
	if *jsonFile != "" {
		// Return true early, before calling a.JSONFile()
		// which will require a GOPATH be set.  This is for
		// integration with Google's build system genrules
		// where there is no GOPATH.
		return true
	}
	// Skip this API if we're in cached mode and the files don't exist on disk.
	if *useCache {
		if _, err := os.Stat(a.JSONFile()); os.IsNotExist(err) {
			return false
		}
	}
	return *apiToGenerate == "*" || *apiToGenerate == a.ID
}

func getAPIs() []*API {
	if *jsonFile != "" {
		return getAPIsFromFile()
	}
	var bytes []byte
	var source string
	apiListFile := filepath.Join(genDirRoot(), "api-list.json")
	if *useCache {
		if !*publicOnly {
			log.Fatalf("-cache=true not compatible with -publiconly=false")
		}
		var err error
		bytes, err = ioutil.ReadFile(apiListFile)
		if err != nil {
			log.Fatal(err)
		}
		source = apiListFile
	} else {
		bytes = slurpURL(*apisURL)
		if *publicOnly {
			if err := writeFile(apiListFile, bytes); err != nil {
				log.Fatal(err)
			}
		}
		source = *apisURL
	}
	apis, err := unmarshalAPIs(bytes)
	if err != nil {
		log.Fatalf("error decoding JSON in %s: %v", source, err)
	}
	if !*publicOnly && *apiToGenerate != "*" {
		apis = append(apis, apiFromID(*apiToGenerate))
	}
	return apis
}

func unmarshalAPIs(bytes []byte) ([]*API, error) {
	var itemObj struct{ Items []*API }
	if err := json.Unmarshal(bytes, &itemObj); err != nil {
		return nil, err
	}
	return itemObj.Items, nil
}

func apiFromID(apiID string) *API {
	parts := strings.Split(apiID, ":")
	if len(parts) != 2 {
		log.Fatalf("malformed API name: %q", apiID)
	}
	return &API{
		ID:      apiID,
		Name:    parts[0],
		Version: parts[1],
	}
}

// getAPIsFromFile handles the case of generating exactly one API
// from the flag given in --api_json_file
func getAPIsFromFile() []*API {
	if *apiToGenerate != "*" {
		log.Fatalf("Can't set --api with --api_json_file.")
	}
	if !*publicOnly {
		log.Fatalf("Can't set --publiconly with --api_json_file.")
	}
	a, err := apiFromFile(*jsonFile)
	if err != nil {
		log.Fatal(err)
	}
	return []*API{a}
}

func apiFromFile(file string) (*API, error) {
	jsonBytes, err := ioutil.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("Error reading %s: %v", file, err)
	}
	doc, err := disco.NewDocument(jsonBytes)
	if err != nil {
		return nil, fmt.Errorf("reading document from %q: %v", file, err)
	}
	a := &API{
		ID:        doc.ID,
		Name:      doc.Name,
		Version:   doc.Version,
		forceJSON: jsonBytes,
		doc:       doc,
	}
	return a, nil
}

func writeFile(file string, contents []byte) error {
	// Don't write it if the contents are identical.
	existing, err := ioutil.ReadFile(file)
	if err == nil && (bytes.Equal(existing, contents) || basicallyEqual(existing, contents)) {
		return nil
	}
	outdir := filepath.Dir(file)
	if err = os.MkdirAll(outdir, 0755); err != nil {
		return fmt.Errorf("failed to Mkdir %s: %v", outdir, err)
	}
	return ioutil.WriteFile(file, contents, 0644)
}

var ignoreLines = regexp.MustCompile(`(?m)^\s+"(?:etag|revision)": ".+\n`)

// basicallyEqual reports whether a and b are equal except for boring
// differences like ETag updates.
func basicallyEqual(a, b []byte) bool {
	return ignoreLines.Match(a) && ignoreLines.Match(b) &&
		bytes.Equal(ignoreLines.ReplaceAll(a, nil), ignoreLines.ReplaceAll(b, nil))
}

func slurpURL(urlStr string) []byte {
	if *useCache {
		log.Fatalf("Invalid use of slurpURL in cached mode for URL %s", urlStr)
	}
	req, err := http.NewRequest("GET", urlStr, nil)
	if err != nil {
		log.Fatal(err)
	}
	if *publicOnly {
		req.Header.Add("X-User-IP", "0.0.0.0") // hack
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatalf("Error fetching URL %s: %v", urlStr, err)
	}
	if res.StatusCode >= 300 {
		log.Printf("WARNING: URL %s served status code %d", urlStr, res.StatusCode)
		return nil
	}
	bs, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Error reading body of URL %s: %v", urlStr, err)
	}
	return bs
}

func panicf(format string, args ...interface{}) {
	panic(fmt.Sprintf(format, args...))
}

// namePool keeps track of used names and assigns free ones based on a
// preferred name
type namePool struct {
	m map[string]bool // lazily initialized
}

// oddVersionRE matches unusual API names like directory_v1.
var oddVersionRE = regexp.MustCompile(`^(.+)_(v[\d\.]+)$`)

// renameVersion conditionally rewrites the provided version such
// that the final path component of the import path doesn't look
// like a Go identifier. This keeps the consistency that import paths
// for the generated Go packages look like:
//     google.golang.org/api/NAME/v<version>
// and have package NAME.
// See https://github.com/google/google-api-go-client/issues/78
func renameVersion(version string) string {
	if version == "alpha" || version == "beta" {
		return "v0." + version
	}
	if m := oddVersionRE.FindStringSubmatch(version); m != nil {
		return m[1] + "/" + m[2]
	}
	return version
}

func (p *namePool) Get(preferred string) string {
	if p.m == nil {
		p.m = make(map[string]bool)
	}
	name := preferred
	tries := 0
	for p.m[name] {
		tries++
		name = fmt.Sprintf("%s%d", preferred, tries)
	}
	p.m[name] = true
	return name
}

func genDirRoot() string {
	if *genDir != "" {
		return *genDir
	}
	paths := filepath.SplitList(os.Getenv("GOPATH"))
	if len(paths) == 0 {
		log.Fatalf("No GOPATH set.")
	}
	return filepath.Join(paths[0], "src", "google.golang.org", "api")
}

func (a *API) SourceDir() string {
	return filepath.Join(genDirRoot(), a.Package(), renameVersion(a.Version))
}

func (a *API) DiscoveryURL() string {
	if a.DiscoveryLink == "" {
		log.Fatalf("API %s has no DiscoveryLink", a.ID)
	}
	return a.DiscoveryLink
}

func (a *API) Package() string {
	return strings.ToLower(a.Name)
}

func (a *API) Target() string {
	return fmt.Sprintf("%s/%s/%s", *apiPackageBase, a.Package(), renameVersion(a.Version))
}

// ServiceType returns the name of the type to use for the root API struct
// (typically "Service").
func (a *API) ServiceType() string {
	switch a.Name {
	case "appengine", "content": // retained for historical compatibility.
		return "APIService"
	default:
		for _, t := range serviceTypes {
			if _, ok := a.schemas[t]; !ok {
				return t
			}
		}
		panic("all service types are used, please consider introducing a new type to serviceTypes.")
	}
}

// GetName returns a free top-level function/type identifier in the package.
// It tries to return your preferred match if it's free.
func (a *API) GetName(preferred string) string {
	return a.usedNames.Get(preferred)
}

func (a *API) apiBaseURL() string {
	var base, rel string
	switch {
	case *baseURL != "":
		base, rel = *baseURL, a.doc.BasePath
	case a.doc.RootURL != "":
		base, rel = a.doc.RootURL, a.doc.ServicePath
	default:
		base, rel = *apisURL, a.doc.BasePath
	}
	return resolveRelative(base, rel)
}

func (a *API) needsDataWrapper() bool {
	for _, feature := range a.doc.Features {
		if feature == "dataWrapper" {
			return true
		}
	}
	return false
}

func (a *API) jsonBytes() []byte {
	if a.forceJSON == nil {
		var slurp []byte
		var err error
		if *useCache {
			slurp, err = ioutil.ReadFile(a.JSONFile())
			if err != nil {
				log.Fatal(err)
			}
		} else {
			slurp = slurpURL(a.DiscoveryURL())
			if slurp != nil {
				// Make sure that keys are sorted by re-marshalling.
				d := make(map[string]interface{})
				json.Unmarshal(slurp, &d)
				if err != nil {
					log.Fatal(err)
				}
				var err error
				slurp, err = json.MarshalIndent(d, "", "  ")
				if err != nil {
					log.Fatal(err)
				}
			}
		}
		a.forceJSON = slurp
	}
	return a.forceJSON
}

func (a *API) JSONFile() string {
	return filepath.Join(a.SourceDir(), a.Package()+"-api.json")
}

var errNoDoc = errors.New("could not read discovery doc")

// WriteGeneratedCode generates code for a.
// It returns errNoDoc if we couldn't read the discovery doc.
func (a *API) WriteGeneratedCode() error {
	genfilename := *output
	jsonBytes := a.jsonBytes()
	// Skip generation if we don't have the discovery doc.
	if jsonBytes == nil {
		// No message here, because slurpURL printed one.
		return errNoDoc
	}
	if genfilename == "" {
		if err := writeFile(a.JSONFile(), jsonBytes); err != nil {
			return err
		}
		outdir := a.SourceDir()
		err := os.MkdirAll(outdir, 0755)
		if err != nil {
			return fmt.Errorf("failed to Mkdir %s: %v", outdir, err)
		}
		pkg := a.Package()
		genfilename = filepath.Join(outdir, pkg+"-gen.go")
	}

	code, err := a.GenerateCode()
	errw := writeFile(genfilename, code)
	if err == nil {
		err = errw
	}
	if err != nil {
		return err
	}
	return nil
}

var docsLink string

func (a *API) GenerateCode() ([]byte, error) {
	pkg := a.Package()

	jsonBytes := a.jsonBytes()
	var err error
	if a.doc == nil {
		a.doc, err = disco.NewDocument(jsonBytes)
		if err != nil {
			return nil, err
		}
	}

	// Buffer the output in memory, for gofmt'ing later.
	var buf bytes.Buffer
	a.p = func(format string, args ...interface{}) {
		_, err := fmt.Fprintf(&buf, format, args...)
		if err != nil {
			panic(err)
		}
	}
	a.pn = func(format string, args ...interface{}) {
		a.p(format+"\n", args...)
	}
	wf := func(path string) error {
		f, err := os.Open(path)
		if err != nil {
			return err
		}
		defer f.Close()

		_, err = io.Copy(&buf, f)
		return err
	}

	p, pn := a.p, a.pn

	if *headerPath != "" {
		if err := wf(*headerPath); err != nil {
			return nil, err
		}
	}

	pn(fmt.Sprintf(`// Copyright %d Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.
`, time.Now().Year()))

	pn("// Package %s provides access to the %s.", pkg, a.doc.Title)
	if r := replacementPackage[pkg]; r != "" {
		pn("//")
		pn("// This package is DEPRECATED. Use package %s instead.", r)
	}
	docsLink = a.doc.DocumentationLink
	if docsLink != "" {
		pn("//")
		pn("// See %s", docsLink)
	}
	pn("//\n// Usage example:")
	pn("//")
	pn("//   import %q", a.Target())
	pn("//   ...")
	pn("//   %sService, err := %s.New(oauthHttpClient)", pkg, pkg)

	pn("package %s // import %q", pkg, a.Target())
	p("\n")
	pn("import (")
	for _, imp := range []string{
		"bytes",
		"context",
		"encoding/json",
		"errors",
		"fmt",
		"io",
		"net/http",
		"net/url",
		"strconv",
		"strings",
	} {
		pn("  %q", imp)
	}
	pn("")
	for _, imp := range []struct {
		pkg   string
		lname string
	}{
		{*gensupportPkg, "gensupport"},
		{*googleapiPkg, "googleapi"},
	} {
		pn("  %s %q", imp.lname, imp.pkg)
	}
	pn(")")
	pn("\n// Always reference these packages, just in case the auto-generated code")
	pn("// below doesn't.")
	pn("var _ = bytes.NewBuffer")
	pn("var _ = strconv.Itoa")
	pn("var _ = fmt.Sprintf")
	pn("var _ = json.NewDecoder")
	pn("var _ = io.Copy")
	pn("var _ = url.Parse")
	pn("var _ = gensupport.MarshalJSON")
	pn("var _ = googleapi.Version")
	pn("var _ = errors.New")
	pn("var _ = strings.Replace")
	pn("var _ = context.Canceled")
	pn("")
	pn("const apiId = %q", a.doc.ID)
	pn("const apiName = %q", a.doc.Name)
	pn("const apiVersion = %q", a.doc.Version)
	pn("const basePath = %q", a.apiBaseURL())

	a.generateScopeConstants()
	a.PopulateSchemas()

	service := a.ServiceType()

	// Reserve names (ignore return value; we're the first caller).
	a.GetName("New")
	a.GetName(service)

	pn("func New(client *http.Client) (*%s, error) {", service)
	pn("if client == nil { return nil, errors.New(\"client is nil\") }")
	pn("s := &%s{client: client, BasePath: basePath}", service)
	for _, res := range a.doc.Resources { // add top level resources.
		pn("s.%s = New%s(s)", resourceGoField(res, nil), resourceGoType(res))
	}
	pn("return s, nil")
	pn("}")

	pn("\ntype %s struct {", service)
	pn(" client *http.Client")
	pn(" BasePath string // API endpoint base URL")
	pn(" UserAgent string // optional additional User-Agent fragment")

	for _, res := range a.doc.Resources {
		pn("\n\t%s\t*%s", resourceGoField(res, nil), resourceGoType(res))
	}
	pn("}")
	pn("\nfunc (s *%s) userAgent() string {", service)
	pn(` if s.UserAgent == "" { return googleapi.UserAgent }`)
	pn(` return googleapi.UserAgent + " " + s.UserAgent`)
	pn("}\n")

	for _, res := range a.doc.Resources {
		a.generateResource(res)
	}

	a.responseTypes = make(map[string]bool)
	for _, meth := range a.APIMethods() {
		meth.cacheResponseTypes(a)
	}
	for _, res := range a.doc.Resources {
		a.cacheResourceResponseTypes(res)
	}

	for _, name := range a.sortedSchemaNames() {
		a.schemas[name].writeSchemaCode(a)
	}

	for _, meth := range a.APIMethods() {
		meth.generateCode()
	}

	for _, res := range a.doc.Resources {
		a.generateResourceMethods(res)
	}

	clean, err := format.Source(buf.Bytes())
	if err != nil {
		return buf.Bytes(), err
	}
	return clean, nil
}

func (a *API) generateScopeConstants() {
	scopes := a.doc.Auth.OAuth2Scopes
	if len(scopes) == 0 {
		return
	}

	a.pn("// OAuth2 scopes used by this API.")
	a.pn("const (")
	n := 0
	for _, scope := range scopes {
		if n > 0 {
			a.p("\n")
		}
		n++
		ident := scopeIdentifierFromURL(scope.URL)
		if scope.Description != "" {
			a.p("%s", asComment("\t", scope.Description))
		}
		a.pn("\t%s = %q", ident, scope.URL)
	}
	a.p(")\n\n")
}

func scopeIdentifierFromURL(urlStr string) string {
	const prefix = "https://www.googleapis.com/auth/"
	if !strings.HasPrefix(urlStr, prefix) {
		const https = "https://"
		if !strings.HasPrefix(urlStr, https) {
			log.Fatalf("Unexpected oauth2 scope %q doesn't start with %q", urlStr, https)
		}
		ident := validGoIdentifer(depunct(urlStr[len(https):], true)) + "Scope"
		return ident
	}
	ident := validGoIdentifer(initialCap(urlStr[len(prefix):])) + "Scope"
	return ident
}

// Schema is a disco.Schema that has been bestowed an identifier, whether by
// having an "id" field at the top of the schema or with an
// automatically generated one in populateSubSchemas.
//
// TODO: While sub-types shouldn't need to be promoted to schemas,
// API.GenerateCode iterates over API.schemas to figure out what
// top-level Go types to write.  These should be separate concerns.
type Schema struct {
	api *API

	typ *disco.Schema

	apiName      string // the native API-defined name of this type
	goName       string // lazily populated by GoName
	goReturnType string // lazily populated by GoReturnType
	props        []*Property
}

type Property struct {
	s              *Schema // the containing Schema
	p              *disco.Property
	assignedGoName string
}

func (p *Property) Type() *disco.Schema {
	return p.p.Schema
}

func (p *Property) GoName() string {
	return initialCap(p.p.Name)
}

func (p *Property) Default() string {
	return p.p.Schema.Default
}

func (p *Property) Description() string {
	return p.p.Schema.Description
}

func (p *Property) Enum() ([]string, bool) {
	typ := p.p.Schema
	if typ.Enums != nil {
		return typ.Enums, true
	}
	// Check if this has an array of string enums.
	if typ.ItemSchema != nil {
		if enums := typ.ItemSchema.Enums; enums != nil && typ.ItemSchema.Type == "string" {
			return enums, true
		}
	}
	return nil, false
}

func (p *Property) EnumDescriptions() []string {
	if desc := p.p.Schema.EnumDescriptions; desc != nil {
		return desc
	}
	// Check if this has an array of string enum descriptions.
	if items := p.p.Schema.ItemSchema; items != nil {
		if desc := items.EnumDescriptions; desc != nil {
			return desc
		}
	}
	return nil
}

func (p *Property) Pattern() (string, bool) {
	return p.p.Schema.Pattern, (p.p.Schema.Pattern != "")
}

func (p *Property) TypeAsGo() string {
	return p.s.api.typeAsGo(p.Type(), false)
}

// A FieldName uniquely identifies a field within a Schema struct for an API.
type fieldName struct {
	api    string // The ID of an API.
	schema string // The Go name of a Schema struct.
	field  string // The Go name of a field.
}

// pointerFields is a list of fields that should use a pointer type.
// This makes it possible to distinguish between a field being unset vs having
// an empty value.
var pointerFields = []fieldName{
	{api: "androidpublisher:v1.1", schema: "InappPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v2", schema: "ProductPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v3", schema: "ProductPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "CancelReason"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "PaymentState"},
	{api: "androidpublisher:v2", schema: "SubscriptionPurchase", field: "PurchaseType"},
	{api: "androidpublisher:v3", schema: "SubscriptionPurchase", field: "PurchaseType"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "BoolValue"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "DoubleValue"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "Int64Value"},
	{api: "cloudmonitoring:v2beta2", schema: "Point", field: "StringValue"},
	{api: "compute:alpha", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "compute:beta", schema: "MetadataItems", field: "Value"},
	{api: "compute:beta", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "compute:v1", schema: "MetadataItems", field: "Value"},
	{api: "compute:v1", schema: "Scheduling", field: "AutomaticRestart"},
	{api: "content:v2", schema: "AccountUser", field: "Admin"},
	{api: "datastore:v1beta2", schema: "Property", field: "BlobKeyValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "BlobValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "BooleanValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "DateTimeValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "DoubleValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "Indexed"},
	{api: "datastore:v1beta2", schema: "Property", field: "IntegerValue"},
	{api: "datastore:v1beta2", schema: "Property", field: "StringValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "BlobValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "BooleanValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "DoubleValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "IntegerValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "StringValue"},
	{api: "datastore:v1beta3", schema: "Value", field: "TimestampValue"},
	{api: "genomics:v1beta2", schema: "Dataset", field: "IsPublic"},
	{api: "monitoring:v3", schema: "TypedValue", field: "BoolValue"},
	{api: "monitoring:v3", schema: "TypedValue", field: "DoubleValue"},
	{api: "monitoring:v3", schema: "TypedValue", field: "Int64Value"},
	{api: "monitoring:v3", schema: "TypedValue", field: "StringValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "BoolValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "DoubleValue"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "Int64Value"},
	{api: "servicecontrol:v1", schema: "MetricValue", field: "StringValue"},
	{api: "sqladmin:v1beta4", schema: "Settings", field: "StorageAutoResize"},
	{api: "storage:v1", schema: "BucketLifecycleRuleCondition", field: "IsLive"},
	{api: "storage:v1beta2", schema: "BucketLifecycleRuleCondition", field: "IsLive"},
	{api: "tasks:v1", schema: "Task", field: "Completed"},
	{api: "youtube:v3", schema: "ChannelSectionSnippet", field: "Position"},
}

// forcePointerType reports whether p should be represented as a pointer type in its parent schema struct.
func (p *Property) forcePointerType() bool {
	if p.UnfortunateDefault() {
		return true
	}

	name := fieldName{api: p.s.api.ID, schema: p.s.GoName(), field: p.GoName()}
	for _, pf := range pointerFields {
		if pf == name {
			return true
		}
	}
	return false
}

// UnfortunateDefault reports whether p may be set to a zero value, but has a non-zero default.
func (p *Property) UnfortunateDefault() bool {
	switch p.TypeAsGo() {
	default:
		return false

	case "bool":
		return p.Default() == "true"

	case "string":
		if p.Default() == "" {
			return false
		}
		// String fields are considered to "allow" a zero value if either:
		//  (a) they are an enum, and one of the permitted enum values is the empty string, or
		//  (b) they have a validation pattern which matches the empty string.
		pattern, hasPat := p.Pattern()
		enum, hasEnum := p.Enum()
		if hasPat && hasEnum {
			log.Printf("Encountered enum property which also has a pattern: %#v", p)
			return false // don't know how to handle this, so ignore.
		}
		return (hasPat && emptyPattern(pattern)) ||
			(hasEnum && emptyEnum(enum))

	case "float64", "int64", "uint64", "int32", "uint32":
		if p.Default() == "" {
			return false
		}
		if f, err := strconv.ParseFloat(p.Default(), 64); err == nil {
			return f != 0.0
		}
		// The default value has an unexpected form.  Whatever it is, it's non-zero.
		return true
	}
}

// emptyPattern reports whether a pattern matches the empty string.
func emptyPattern(pattern string) bool {
	if re, err := regexp.Compile(pattern); err == nil {
		return re.MatchString("")
	}
	log.Printf("Encountered bad pattern: %s", pattern)
	return false
}

// emptyEnum reports whether a property enum list contains the empty string.
func emptyEnum(enum []string) bool {
	for _, val := range enum {
		if val == "" {
			return true
		}
	}
	return false
}

func (a *API) typeAsGo(s *disco.Schema, elidePointers bool) string {
	switch s.Kind {
	case disco.SimpleKind:
		return mustSimpleTypeConvert(s.Type, s.Format)
	case disco.ArrayKind:
		as := s.ElementSchema()
		if as.Type == "string" {
			switch as.Format {
			case "int64":
				return "googleapi.Int64s"
			case "uint64":
				return "googleapi.Uint64s"
			case "int32":
				return "googleapi.Int32s"
			case "uint32":
				return "googleapi.Uint32s"
			case "float64":
				return "googleapi.Float64s"
			}
		}
		return "[]" + a.typeAsGo(as, elidePointers)
	case disco.ReferenceKind:
		rs := s.RefSchema
		if rs.Kind == disco.SimpleKind {
			// Simple top-level schemas get named types (see writeSchemaCode).
			// Use the name instead of using the equivalent simple Go type.
			return a.schemaNamed(rs.Name).GoName()
		}
		return a.typeAsGo(rs, elidePointers)
	case disco.MapKind:
		es := s.ElementSchema()
		if es.Type == "string" {
			// If the element schema has a type "string", it's going to be
			// transmitted as a string, and the Go map type must reflect that.
			// This is true even if the format is, say, "int64". When type =
			// "string" and format = "int64" at top level, we can use the json
			// "string" tag option to unmarshal the string to an int64, but
			// inside a map we can't.
			return "map[string]string"
		}
		// Due to historical baggage (maps used to be a separate code path),
		// the element types of maps never have pointers in them.  From this
		// level down, elide pointers in types.
		return "map[string]" + a.typeAsGo(es, true)
	case disco.AnyStructKind:
		return "googleapi.RawMessage"
	case disco.StructKind:
		tls := a.schemaNamed(s.Name)
		if elidePointers || s.Variant != nil {
			return tls.GoName()
		}
		return "*" + tls.GoName()
	default:
		panic(fmt.Sprintf("unhandled typeAsGo for %+v", s))
	}
}

func (a *API) schemaNamed(name string) *Schema {
	s := a.schemas[name]
	if s == nil {
		panicf("no top-level schema named %q", name)
	}
	return s
}

func (s *Schema) properties() []*Property {
	if s.props != nil {
		return s.props
	}
	if s.typ.Kind != disco.StructKind {
		panic("called properties on non-object schema")
	}
	for _, p := range s.typ.Properties {
		s.props = append(s.props, &Property{
			s: s,
			p: p,
		})
	}
	return s.props
}

func (s *Schema) HasContentType() bool {
	for _, p := range s.properties() {
		if p.GoName() == "ContentType" && p.TypeAsGo() == "string" {
			return true
		}
	}
	return false
}

func (s *Schema) populateSubSchemas() (outerr error) {
	defer func() {
		r := recover()
		if r == nil {
			return
		}
		outerr = fmt.Errorf("%v", r)
	}()

	addSubStruct := func(subApiName string, t *disco.Schema) {
		if s.api.schemas[subApiName] != nil {
			panic("dup schema apiName: " + subApiName)
		}
		if t.Name != "" {
			panic("subtype already has name: " + t.Name)
		}
		t.Name = subApiName
		subs := &Schema{
			api:     s.api,
			typ:     t,
			apiName: subApiName,
		}
		s.api.schemas[subApiName] = subs
		err := subs.populateSubSchemas()
		if err != nil {
			panicf("in sub-struct %q: %v", subApiName, err)
		}
	}

	switch s.typ.Kind {
	case disco.StructKind:
		for _, p := range s.properties() {
			subApiName := fmt.Sprintf("%s.%s", s.apiName, p.p.Name)
			switch p.Type().Kind {
			case disco.SimpleKind, disco.ReferenceKind, disco.AnyStructKind:
				// Do nothing.
			case disco.MapKind:
				mt := p.Type().ElementSchema()
				if mt.Kind == disco.SimpleKind || mt.Kind == disco.ReferenceKind {
					continue
				}
				addSubStruct(subApiName, mt)
			case disco.ArrayKind:
				at := p.Type().ElementSchema()
				if at.Kind == disco.SimpleKind || at.Kind == disco.ReferenceKind {
					continue
				}
				addSubStruct(subApiName, at)
			case disco.StructKind:
				addSubStruct(subApiName, p.Type())
			default:
				panicf("Unknown type for %q: %v", subApiName, p.Type())
			}
		}
	case disco.ArrayKind:
		subApiName := fmt.Sprintf("%s.Item", s.apiName)
		switch at := s.typ.ElementSchema(); at.Kind {
		case disco.SimpleKind, disco.ReferenceKind, disco.AnyStructKind:
			// Do nothing.
		case disco.MapKind:
			mt := at.ElementSchema()
			if k := mt.Kind; k != disco.SimpleKind && k != disco.ReferenceKind {
				addSubStruct(subApiName, mt)
			}
		case disco.ArrayKind:
			at := at.ElementSchema()
			if k := at.Kind; k != disco.SimpleKind && k != disco.ReferenceKind {
				addSubStruct(subApiName, at)
			}
		case disco.StructKind:
			addSubStruct(subApiName, at)
		default:
			panicf("Unknown array type for %q: %v", subApiName, at)
		}
	case disco.AnyStructKind, disco.MapKind, disco.SimpleKind, disco.ReferenceKind:
		// Do nothing.
	default:
		fmt.Fprintf(os.Stderr, "in populateSubSchemas, schema is: %v", s.typ)
		panicf("populateSubSchemas: unsupported type for schema %q", s.apiName)
		panic("unreachable")
	}
	return nil
}

// GoName returns (or creates and returns) the bare Go name
// of the apiName, making sure that it's a proper Go identifier
// and doesn't conflict with an existing name.
func (s *Schema) GoName() string {
	if s.goName == "" {
		if s.typ.Kind == disco.MapKind {
			s.goName = s.api.typeAsGo(s.typ, false)
		} else {
			base := initialCap(s.apiName)
			s.goName = s.api.GetName(base)
			if base == "Service" && s.goName != "Service" {
				// Detect the case where a resource is going to clash with the
				// root service object.
				panicf("Clash on name Service")
			}
		}
	}
	return s.goName
}

// GoReturnType returns the Go type to use as the return type.
// If a type is a struct, it will return *StructType,
// for a map it will return map[string]ValueType,
// for (not yet supported) slices it will return []ValueType.
func (s *Schema) GoReturnType() string {
	if s.goReturnType == "" {
		if s.typ.Kind == disco.MapKind {
			s.goReturnType = s.GoName()
		} else {
			s.goReturnType = "*" + s.GoName()
		}
	}
	return s.goReturnType
}

func (s *Schema) writeSchemaCode(api *API) {
	switch s.typ.Kind {
	case disco.SimpleKind:
		apitype := s.typ.Type
		typ := mustSimpleTypeConvert(apitype, s.typ.Format)
		s.api.pn("\ntype %s %s", s.GoName(), typ)
	case disco.StructKind:
		s.writeSchemaStruct(api)
	case disco.MapKind, disco.AnyStructKind:
		// Do nothing.
	case disco.ArrayKind:
		log.Printf("TODO writeSchemaCode for arrays for %s", s.GoName())
	default:
		fmt.Fprintf(os.Stderr, "in writeSchemaCode, schema is: %+v", s.typ)
		panicf("writeSchemaCode: unsupported type for schema %q", s.apiName)
	}
}

func (s *Schema) writeVariant(api *API, v *disco.Variant) {
	s.api.p("\ntype %s map[string]interface{}\n\n", s.GoName())

	// Write out the "Type" method that identifies the variant type.
	s.api.pn("func (t %s) Type() string {", s.GoName())
	s.api.pn("  return googleapi.VariantType(t)")
	s.api.p("}\n\n")

	// Write out helper methods to convert each possible variant.
	for _, m := range v.Map {
		if m.TypeValue == "" && m.Ref == "" {
			log.Printf("TODO variant %s ref %s not yet supported.", m.TypeValue, m.Ref)
			continue
		}

		s.api.pn("func (t %s) %s() (r %s, ok bool) {", s.GoName(), initialCap(m.TypeValue), m.Ref)
		s.api.pn(" if t.Type() != %q {", initialCap(m.TypeValue))
		s.api.pn("  return r, false")
		s.api.pn(" }")
		s.api.pn(" ok = googleapi.ConvertVariant(map[string]interface{}(t), &r)")
		s.api.pn(" return r, ok")
		s.api.p("}\n\n")
	}
}

func (s *Schema) Description() string {
	return s.typ.Description
}

func (s *Schema) writeSchemaStruct(api *API) {
	if v := s.typ.Variant; v != nil {
		s.writeVariant(api, v)
		return
	}
	s.api.p("\n")
	des := s.Description()
	if des != "" {
		s.api.p("%s", asComment("", fmt.Sprintf("%s: %s", s.GoName(), des)))
	}
	s.api.pn("type %s struct {", s.GoName())

	np := new(namePool)
	forceSendName := np.Get("ForceSendFields")
	nullFieldsName := np.Get("NullFields")
	if s.isResponseType() {
		np.Get("ServerResponse") // reserve the name
	}

	firstFieldName := "" // used to store a struct field name for use in documentation.
	for i, p := range s.properties() {
		if i > 0 {
			s.api.p("\n")
		}
		pname := np.Get(p.GoName())
		if pname[0] == '@' {
			// HACK(cbro): ignore JSON-LD special fields until we can figure out
			// the correct Go representation for them.
			continue
		}
		p.assignedGoName = pname
		des := p.Description()
		if des != "" {
			s.api.p("%s", asComment("\t", fmt.Sprintf("%s: %s", pname, des)))
		}
		addFieldValueComments(s.api.p, p, "\t", des != "")

		var extraOpt string
		if p.Type().IsIntAsString() {
			extraOpt += ",string"
		}

		typ := p.TypeAsGo()
		if p.forcePointerType() {
			typ = "*" + typ
		}

		s.api.pn(" %s %s `json:\"%s,omitempty%s\"`", pname, typ, p.p.Name, extraOpt)
		if firstFieldName == "" {
			firstFieldName = pname
		}
	}

	if s.isResponseType() {
		if firstFieldName != "" {
			s.api.p("\n")
		}
		s.api.p("%s", asComment("\t", "ServerResponse contains the HTTP response code and headers from the server."))
		s.api.pn(" googleapi.ServerResponse `json:\"-\"`")
	}

	if firstFieldName == "" {
		// There were no fields in the struct, so there is no point
		// adding any custom JSON marshaling code.
		s.api.pn("}")
		return
	}

	commentFmtStr := "%s is a list of field names (e.g. %q) to " +
		"unconditionally include in API requests. By default, fields " +
		"with empty values are omitted from API requests. However, " +
		"any non-pointer, non-interface field appearing in %s will " +
		"be sent to the server regardless of whether the field is " +
		"empty or not. This may be used to include empty fields in " +
		"Patch requests."
	comment := fmt.Sprintf(commentFmtStr, forceSendName, firstFieldName, forceSendName)
	s.api.p("\n")
	s.api.p("%s", asComment("\t", comment))

	s.api.pn("\t%s []string `json:\"-\"`", forceSendName)

	commentFmtStr = "%s is a list of field names (e.g. %q) to " +
		"include in API requests with the JSON null value. " +
		"By default, fields with empty values are omitted from API requests. However, " +
		"any field with an empty value appearing in %s will be sent to the server as null. " +
		"It is an error if a field in this list has a non-empty value. This may be used to " +
		"include null fields in Patch requests."
	comment = fmt.Sprintf(commentFmtStr, nullFieldsName, firstFieldName, nullFieldsName)
	s.api.p("\n")
	s.api.p("%s", asComment("\t", comment))

	s.api.pn("\t%s []string `json:\"-\"`", nullFieldsName)

	s.api.pn("}")
	s.writeSchemaMarshal(forceSendName, nullFieldsName)
	s.writeSchemaUnmarshal()
}

// writeSchemaMarshal writes a custom MarshalJSON function for s, which allows
// fields to be explicitly transmitted by listing them in the field identified
// by forceSendFieldName, and allows fields to be transmitted with the null value
// by listing them in the field identified by nullFieldsName.
func (s *Schema) writeSchemaMarshal(forceSendFieldName, nullFieldsName string) {
	s.api.pn("func (s *%s) MarshalJSON() ([]byte, error) {", s.GoName())
	s.api.pn("\ttype NoMethod %s", s.GoName())
	// pass schema as methodless type to prevent subsequent calls to MarshalJSON from recursing indefinitely.
	s.api.pn("\traw := NoMethod(*s)")
	s.api.pn("\treturn gensupport.MarshalJSON(raw, s.%s, s.%s)", forceSendFieldName, nullFieldsName)
	s.api.pn("}")
}

func (s *Schema) writeSchemaUnmarshal() {
	var floatProps []*Property
	for _, p := range s.properties() {
		if p.p.Schema.Type == "number" {
			floatProps = append(floatProps, p)
		}
	}
	if len(floatProps) == 0 {
		return
	}
	pn := s.api.pn
	pn("\nfunc (s *%s) UnmarshalJSON(data []byte) error {", s.GoName())
	pn("  type NoMethod %s", s.GoName()) // avoid infinite recursion
	pn("  var s1 struct {")
	// Hide the float64 fields of the schema with fields that correctly
	// unmarshal special values.
	for _, p := range floatProps {
		typ := "gensupport.JSONFloat64"
		if p.forcePointerType() {
			typ = "*" + typ
		}
		pn("%s %s `json:\"%s\"`", p.assignedGoName, typ, p.p.Name)
	}
	pn("    *NoMethod") // embed the schema
	pn("  }")
	// Set the schema value into the wrapper so its other fields are unmarshaled.
	pn("  s1.NoMethod = (*NoMethod)(s)")
	pn("  if err := json.Unmarshal(data, &s1); err != nil {")
	pn("    return err")
	pn("  }")
	// Copy each shadowing field into the field it shadows.
	for _, p := range floatProps {
		n := p.assignedGoName
		if p.forcePointerType() {
			pn("if s1.%s != nil { s.%s = (*float64)(s1.%s) }", n, n, n)
		} else {
			pn("s.%s = float64(s1.%s)", n, n)
		}
	}
	pn(" return nil")
	pn("}")
}

// isResponseType returns true for all types that are used as a response.
func (s *Schema) isResponseType() bool {
	return s.api.responseTypes["*"+s.goName]
}

// PopulateSchemas reads all the API types ("schemas") from the JSON file
// and converts them to *Schema instances, returning an identically
// keyed map, additionally containing subresources.  For instance,
//
// A resource "Foo" of type "object" with a property "bar", also of type
// "object" (an anonymous sub-resource), will get a synthetic API name
// of "Foo.bar".
//
// A resource "Foo" of type "array" with an "items" of type "object"
// will get a synthetic API name of "Foo.Item".
func (a *API) PopulateSchemas() {
	if a.schemas != nil {
		panic("")
	}
	a.schemas = make(map[string]*Schema)
	for name, ds := range a.doc.Schemas {
		s := &Schema{
			api:     a,
			apiName: name,
			typ:     ds,
		}
		a.schemas[name] = s
		err := s.populateSubSchemas()
		if err != nil {
			panicf("Error populating schema with API name %q: %v", name, err)
		}
	}
}

func (a *API) generateResource(r *disco.Resource) {
	pn := a.pn
	t := resourceGoType(r)
	pn(fmt.Sprintf("func New%s(s *%s) *%s {", t, a.ServiceType(), t))
	pn("rs := &%s{s : s}", t)
	for _, res := range r.Resources {
		pn("rs.%s = New%s(s)", resourceGoField(res, r), resourceGoType(res))
	}
	pn("return rs")
	pn("}")

	pn("\ntype %s struct {", t)
	pn(" s *%s", a.ServiceType())
	for _, res := range r.Resources {
		pn("\n\t%s\t*%s", resourceGoField(res, r), resourceGoType(res))
	}
	pn("}")

	for _, res := range r.Resources {
		a.generateResource(res)
	}
}

func (a *API) cacheResourceResponseTypes(r *disco.Resource) {
	for _, meth := range a.resourceMethods(r) {
		meth.cacheResponseTypes(a)
	}
	for _, res := range r.Resources {
		a.cacheResourceResponseTypes(res)
	}
}

func (a *API) generateResourceMethods(r *disco.Resource) {
	for _, meth := range a.resourceMethods(r) {
		meth.generateCode()
	}
	for _, res := range r.Resources {
		a.generateResourceMethods(res)
	}
}

func resourceGoField(r, parent *disco.Resource) string {
	// Avoid conflicts with method names.
	und := ""
	if parent != nil {
		for _, m := range parent.Methods {
			if m.Name == r.Name {
				und = "_"
				break
			}
		}
	}
	// Note: initialCap(r.Name + "_") doesn't work because initialCap calls depunct.
	return initialCap(r.Name) + und
}

func resourceGoType(r *disco.Resource) string {
	return initialCap(r.FullName + "Service")
}

func (a *API) resourceMethods(r *disco.Resource) []*Method {
	ms := []*Method{}
	for _, m := range r.Methods {
		ms = append(ms, &Method{
			api: a,
			r:   r,
			m:   m,
		})
	}
	return ms
}

type Method struct {
	api *API
	r   *disco.Resource // or nil if a API-level (top-level) method
	m   *disco.Method

	params []*Param // all Params, of each type, lazily set by first call of Params method.
}

func (m *Method) Id() string {
	return m.m.ID
}

func (m *Method) responseType() *Schema {
	return m.api.schemas[m.m.Response.RefSchema.Name]
}

func (m *Method) supportsMediaUpload() bool {
	return m.m.MediaUpload != nil
}

func (m *Method) mediaUploadPath() string {
	return m.m.MediaUpload.Protocols["simple"].Path
}

func (m *Method) supportsMediaDownload() bool {
	if m.supportsMediaUpload() {
		// storage.objects.insert claims support for download in
		// addition to upload but attempting to do so fails.
		// This situation doesn't apply to any other methods.
		return false
	}
	return m.m.SupportsMediaDownload
}

func (m *Method) supportsPaging() (*pageTokenGenerator, string, bool) {
	ptg := m.pageTokenGenerator()
	if ptg == nil {
		return nil, "", false
	}

	// Check that the response type has the next page token.
	s := m.responseType()
	if s == nil || s.typ.Kind != disco.StructKind {
		return nil, "", false
	}
	for _, prop := range s.properties() {
		if isPageTokenName(prop.p.Name) && prop.Type().Type == "string" {
			return ptg, prop.GoName(), true
		}
	}

	return nil, "", false
}

type pageTokenGenerator struct {
	isParam     bool   // is the page token a URL parameter?
	name        string // param or request field name
	requestName string // empty for URL param
}

func (p *pageTokenGenerator) genGet() string {
	if p.isParam {
		return fmt.Sprintf("c.urlParams_.Get(%q)", p.name)
	}
	return fmt.Sprintf("c.%s.%s", p.requestName, p.name)
}

func (p *pageTokenGenerator) genSet(valueExpr string) string {
	if p.isParam {
		return fmt.Sprintf("c.%s(%s)", initialCap(p.name), valueExpr)
	}
	return fmt.Sprintf("c.%s.%s = %s", p.requestName, p.name, valueExpr)
}

func (p *pageTokenGenerator) genDeferBody() string {
	if p.isParam {
		return p.genSet(p.genGet())
	}
	return fmt.Sprintf("func (pt string) { %s }(%s)", p.genSet("pt"), p.genGet())
}

// pageTokenGenerator returns a pageTokenGenerator that will generate code to
// get/set the page token for a subsequent page in the context of the generated
// Pages method. It returns nil if there is no page token.
func (m *Method) pageTokenGenerator() *pageTokenGenerator {
	matches := m.grepParams(func(p *Param) bool { return isPageTokenName(p.p.Name) })
	switch len(matches) {
	case 1:
		if matches[0].p.Required {
			// The page token is a required parameter (e.g. because there is
			// a separate API call to start an iteration), and so the relevant
			// call factory method takes the page token instead.
			return nil
		}
		n := matches[0].p.Name
		return &pageTokenGenerator{true, n, ""}

	case 0: // No URL parameter, but maybe a request field.
		if m.m.Request == nil {
			return nil
		}
		rs := m.m.Request
		if rs.RefSchema != nil {
			rs = rs.RefSchema
		}
		for _, p := range rs.Properties {
			if isPageTokenName(p.Name) {
				return &pageTokenGenerator{false, initialCap(p.Name), validGoIdentifer(strings.ToLower(rs.Name))}
			}
		}
		return nil

	default:
		panicf("too many page token parameters for method %s", m.m.Name)
		return nil
	}
}

func isPageTokenName(s string) bool {
	return s == "pageToken" || s == "nextPageToken"
}

func (m *Method) Params() []*Param {
	if m.params == nil {
		for _, p := range m.m.Parameters {
			m.params = append(m.params, &Param{
				method: m,
				p:      p,
			})
		}
	}
	return m.params
}

func (m *Method) grepParams(f func(*Param) bool) []*Param {
	matches := make([]*Param, 0)
	for _, param := range m.Params() {
		if f(param) {
			matches = append(matches, param)
		}
	}
	return matches
}

func (m *Method) NamedParam(name string) *Param {
	matches := m.grepParams(func(p *Param) bool {
		return p.p.Name == name
	})
	if len(matches) < 1 {
		log.Panicf("failed to find named parameter %q", name)
	}
	if len(matches) > 1 {
		log.Panicf("found multiple parameters for parameter name %q", name)
	}
	return matches[0]
}

func (m *Method) OptParams() []*Param {
	return m.grepParams(func(p *Param) bool {
		return !p.p.Required
	})
}

func (meth *Method) cacheResponseTypes(api *API) {
	if retType := responseType(api, meth.m); retType != "" && strings.HasPrefix(retType, "*") {
		api.responseTypes[retType] = true
	}
}

// convertMultiParams builds a []string temp variable from a slice
// of non-strings and returns the name of the temp variable.
func convertMultiParams(a *API, param string) string {
	a.pn(" var %v_ []string", param)
	a.pn(" for _, v := range %v {", param)
	a.pn("  %v_ = append(%v_, fmt.Sprint(v))", param, param)
	a.pn(" }")
	return param + "_"
}

func (meth *Method) generateCode() {
	res := meth.r // may be nil if a top-level method
	a := meth.api
	p, pn := a.p, a.pn

	pn("\n// method id %q:", meth.Id())

	retType := responseType(a, meth.m)
	retTypeComma := retType
	if retTypeComma != "" {
		retTypeComma += ", "
	}

	args := meth.NewArguments()
	methodName := initialCap(meth.m.Name)
	prefix := ""
	if res != nil {
		prefix = initialCap(res.FullName)
	}
	callName := a.GetName(prefix + methodName + "Call")

	pn("\ntype %s struct {", callName)
	pn(" s *%s", a.ServiceType())
	for _, arg := range args.l {
		if arg.location != "query" {
			pn(" %s %s", arg.goname, arg.gotype)
		}
	}
	pn(" urlParams_ gensupport.URLParams")
	httpMethod := meth.m.HTTPMethod
	if httpMethod == "GET" {
		pn(" ifNoneMatch_ string")
	}

	if meth.supportsMediaUpload() {
		pn(" mediaInfo_ *gensupport.MediaInfo")
	}
	pn(" ctx_ context.Context")
	pn(" header_ http.Header")
	pn("}")

	p("\n%s", asComment("", methodName+": "+meth.m.Description))
	if res != nil {
		if url := canonicalDocsURL[fmt.Sprintf("%v%v/%v", docsLink, res.Name, meth.m.Name)]; url != "" {
			pn("// For details, see %v", url)
		}
	}

	var servicePtr string
	if res == nil {
		pn("func (s *Service) %s(%s) *%s {", methodName, args, callName)
		servicePtr = "s"
	} else {
		pn("func (r *%s) %s(%s) *%s {", resourceGoType(res), methodName, args, callName)
		servicePtr = "r.s"
	}

	pn(" c := &%s{s: %s, urlParams_: make(gensupport.URLParams)}", callName, servicePtr)
	for _, arg := range args.l {
		// TODO(gmlewis): clean up and consolidate this section.
		// See: https://code-review.googlesource.com/#/c/3520/18/google-api-go-generator/gen.go
		if arg.location == "query" {
			switch arg.gotype {
			case "[]string":
				pn(" c.urlParams_.SetMulti(%q, append([]string{}, %v...))", arg.apiname, arg.goname)
			case "string":
				pn(" c.urlParams_.Set(%q, %v)", arg.apiname, arg.goname)
			default:
				if strings.HasPrefix(arg.gotype, "[]") {
					tmpVar := convertMultiParams(a, arg.goname)
					pn(" c.urlParams_.SetMulti(%q, %v)", arg.apiname, tmpVar)
				} else {
					pn(" c.urlParams_.Set(%q, fmt.Sprint(%v))", arg.apiname, arg.goname)
				}
			}
			continue
		}
		if arg.gotype == "[]string" {
			pn(" c.%s = append([]string{}, %s...)", arg.goname, arg.goname) // Make a copy of the []string.
			continue
		}
		pn(" c.%s = %s", arg.goname, arg.goname)
	}
	pn(" return c")
	pn("}")

	for _, opt := range meth.OptParams() {
		if opt.p.Location != "query" {
			panicf("optional parameter has unsupported location %q", opt.p.Location)
		}
		setter := initialCap(opt.p.Name)
		des := opt.p.Description
		des = strings.Replace(des, "Optional.", "", 1)
		des = strings.TrimSpace(des)
		p("\n%s", asComment("", fmt.Sprintf("%s sets the optional parameter %q: %s", setter, opt.p.Name, des)))
		addFieldValueComments(p, opt, "", true)
		np := new(namePool)
		np.Get("c") // take the receiver's name
		paramName := np.Get(validGoIdentifer(opt.p.Name))
		typePrefix := ""
		if opt.p.Repeated {
			typePrefix = "..."
		}
		pn("func (c *%s) %s(%s %s%s) *%s {", callName, setter, paramName, typePrefix, opt.GoType(), callName)
		if opt.p.Repeated {
			if opt.GoType() == "string" {
				pn("c.urlParams_.SetMulti(%q, append([]string{}, %v...))", opt.p.Name, paramName)
			} else {
				tmpVar := convertMultiParams(a, paramName)
				pn(" c.urlParams_.SetMulti(%q, %v)", opt.p.Name, tmpVar)
			}
		} else {
			if opt.GoType() == "string" {
				pn("c.urlParams_.Set(%q, %v)", opt.p.Name, paramName)
			} else {
				pn("c.urlParams_.Set(%q, fmt.Sprint(%v))", opt.p.Name, paramName)
			}
		}
		pn("return c")
		pn("}")
	}

	if meth.supportsMediaUpload() {
		comment := "Media specifies the media to upload in one or more chunks. " +
			"The chunk size may be controlled by supplying a MediaOption generated by googleapi.ChunkSize. " +
			"The chunk size defaults to googleapi.DefaultUploadChunkSize." +
			"The Content-Type header used in the upload request will be determined by sniffing the contents of r, " +
			"unless a MediaOption generated by googleapi.ContentType is supplied." +
			"\nAt most one of Media and ResumableMedia may be set."
		// TODO(mcgreevy): Ensure that r is always closed before Do returns, and document this.
		// See comments on https://code-review.googlesource.com/#/c/3970/
		p("\n%s", asComment("", comment))
		pn("func (c *%s) Media(r io.Reader, options ...googleapi.MediaOption) *%s {", callName, callName)
		// We check if the body arg, if any, has a content type and apply it here.
		// In practice, this only happens for the storage API today.
		// TODO(djd): check if we can cope with the developer setting the body's Content-Type field
		// after they've made this call.
		if ba := args.bodyArg(); ba != nil {
			if ba.schema.HasContentType() {
				pn("  if ct := c.%s.ContentType; ct != \"\" {", ba.goname)
				pn("   options = append([]googleapi.MediaOption{googleapi.ContentType(ct)}, options...)")
				pn("  }")
			}
		}
		pn(" c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)")
		pn(" return c")
		pn("}")
		comment = "ResumableMedia specifies the media to upload in chunks and can be canceled with ctx. " +
			"\n\nDeprecated: use Media instead." +
			"\n\nAt most one of Media and ResumableMedia may be set. " +
			`mediaType identifies the MIME media type of the upload, such as "image/png". ` +
			`If mediaType is "", it will be auto-detected. ` +
			`The provided ctx will supersede any context previously provided to ` +
			`the Context method.`
		p("\n%s", asComment("", comment))
		pn("func (c *%s) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *%s {", callName, callName)
		pn(" c.ctx_ = ctx")
		pn(" c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)")
		pn(" return c")
		pn("}")
		comment = "ProgressUpdater provides a callback function that will be called after every chunk. " +
			"It should be a low-latency function in order to not slow down the upload operation. " +
			"This should only be called when using ResumableMedia (as opposed to Media)."
		p("\n%s", asComment("", comment))
		pn("func (c *%s) ProgressUpdater(pu googleapi.ProgressUpdater) *%s {", callName, callName)
		pn(`c.mediaInfo_.SetProgressUpdater(pu)`)
		pn("return c")
		pn("}")
	}

	comment := "Fields allows partial responses to be retrieved. " +
		"See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse " +
		"for more information."
	p("\n%s", asComment("", comment))
	pn("func (c *%s) Fields(s ...googleapi.Field) *%s {", callName, callName)
	pn(`c.urlParams_.Set("fields", googleapi.CombineFields(s))`)
	pn("return c")
	pn("}")
	if httpMethod == "GET" {
		// Note that non-GET responses are excluded from supporting If-None-Match.
		// See https://github.com/google/google-api-go-client/issues/107 for more info.
		comment := "IfNoneMatch sets the optional parameter which makes the operation fail if " +
			"the object's ETag matches the given value. This is useful for getting updates " +
			"only after the object has changed since the last request. " +
			"Use googleapi.IsNotModified to check whether the response error from Do " +
			"is the result of In-None-Match."
		p("\n%s", asComment("", comment))
		pn("func (c *%s) IfNoneMatch(entityTag string) *%s {", callName, callName)
		pn(" c.ifNoneMatch_ = entityTag")
		pn(" return c")
		pn("}")
	}

	doMethod := "Do method"
	if meth.supportsMediaDownload() {
		doMethod = "Do and Download methods"
	}
	commentFmtStr := "Context sets the context to be used in this call's %s. " +
		"Any pending HTTP request will be aborted if the provided context is canceled."
	comment = fmt.Sprintf(commentFmtStr, doMethod)
	p("\n%s", asComment("", comment))
	if meth.supportsMediaUpload() {
		comment = "This context will supersede any context previously provided to " +
			"the ResumableMedia method."
		p("%s", asComment("", comment))
	}
	pn("func (c *%s) Context(ctx context.Context) *%s {", callName, callName)
	pn(`c.ctx_ = ctx`)
	pn("return c")
	pn("}")

	comment = "Header returns an http.Header that can be modified by the caller to add " +
		"HTTP headers to the request."
	p("\n%s", asComment("", comment))
	pn("func (c *%s) Header() http.Header {", callName)
	pn(" if c.header_ == nil {")
	pn("  c.header_ = make(http.Header)")
	pn(" }")
	pn(" return c.header_")
	pn("}")

	pn("\nfunc (c *%s) doRequest(alt string) (*http.Response, error) {", callName)
	pn(`reqHeaders := make(http.Header)`)
	pn("for k, v := range c.header_ {")
	pn(" reqHeaders[k] = v")
	pn("}")
	pn(`reqHeaders.Set("User-Agent",c.s.userAgent())`)
	if httpMethod == "GET" {
		pn(`if c.ifNoneMatch_ != "" {`)
		pn(` reqHeaders.Set("If-None-Match",  c.ifNoneMatch_)`)
		pn("}")
	}
	pn("var body io.Reader = nil")
	if ba := args.bodyArg(); ba != nil && httpMethod != "GET" {
		if meth.m.ID == "ml.projects.predict" {
			// Skip JSONReader for APIs that require clients to pass in JSON already.
			pn("body = strings.NewReader(c.%s.HttpBody.Data)", ba.goname)
		} else {
			style := "WithoutDataWrapper"
			if a.needsDataWrapper() {
				style = "WithDataWrapper"
			}
			pn("body, err := googleapi.%s.JSONReader(c.%s)", style, ba.goname)
			pn("if err != nil { return nil, err }")
		}

		pn(`reqHeaders.Set("Content-Type", "application/json")`)
	}
	pn(`c.urlParams_.Set("alt", alt)`)
	pn(`c.urlParams_.Set("prettyPrint", "false")`)

	pn("urls := googleapi.ResolveRelative(c.s.BasePath, %q)", meth.m.Path)
	if meth.supportsMediaUpload() {
		pn("if c.mediaInfo_ != nil {")
		// Hack guess, since we get a 404 otherwise:
		//pn("urls = googleapi.ResolveRelative(%q, %q)", a.apiBaseURL(), meth.mediaUploadPath())
		// Further hack.  Discovery doc is wrong?
		pn("  urls = strings.Replace(urls, %q, %q, 1)", "https://www.googleapis.com/", "https://www.googleapis.com/upload/")
		pn(`  c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())`)
		pn("}")

		pn("if body == nil {")
		pn(" body = new(bytes.Buffer)")
		pn(` reqHeaders.Set("Content-Type", "application/json")`)
		pn("}")
		pn("body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)")
		pn("defer cleanup()")
	}
	pn("urls += \"?\" + c.urlParams_.Encode()")
	pn("req, err := http.NewRequest(%q, urls, body)", httpMethod)
	pn("if err != nil { return nil, err }")
	pn("req.Header = reqHeaders")
	if meth.supportsMediaUpload() {
		pn("req.GetBody = getBody")
	}

	// Replace param values after NewRequest to avoid reencoding them.
	// E.g. Cloud Storage API requires '%2F' in entity param to be kept, but url.Parse replaces it with '/'.
	argsForLocation := args.forLocation("path")
	if len(argsForLocation) > 0 {
		pn(`googleapi.Expand(req.URL, map[string]string{`)
		for _, arg := range argsForLocation {
			pn(`"%s": %s,`, arg.apiname, arg.exprAsString("c."))
		}
		pn(`})`)
	}

	pn("return gensupport.SendRequest(c.ctx_, c.s.client, req)")
	pn("}")

	if meth.supportsMediaDownload() {
		pn("\n// Download fetches the API endpoint's \"media\" value, instead of the normal")
		pn("// API response value. If the returned error is nil, the Response is guaranteed to")
		pn("// have a 2xx status code. Callers must close the Response.Body as usual.")
		pn("func (c *%s) Download(opts ...googleapi.CallOption) (*http.Response, error) {", callName)
		pn(`gensupport.SetOptions(c.urlParams_, opts...)`)
		pn(`res, err := c.doRequest("media")`)
		pn("if err != nil { return nil, err }")
		pn("if err := googleapi.CheckMediaResponse(res); err != nil {")
		pn("res.Body.Close()")
		pn("return nil, err")
		pn("}")
		pn("return res, nil")
		pn("}")
	}

	mapRetType := strings.HasPrefix(retTypeComma, "map[")
	pn("\n// Do executes the %q call.", meth.m.ID)
	if retTypeComma != "" && !mapRetType {
		commentFmtStr := "Exactly one of %v or error will be non-nil. " +
			"Any non-2xx status code is an error. " +
			"Response headers are in either %v.ServerResponse.Header " +
			"or (if a response was returned at all) in error.(*googleapi.Error).Header. " +
			"Use googleapi.IsNotModified to check whether the returned error was because " +
			"http.StatusNotModified was returned."
		comment := fmt.Sprintf(commentFmtStr, retType, retType)
		p("%s", asComment("", comment))
	}
	pn("func (c *%s) Do(opts ...googleapi.CallOption) (%serror) {", callName, retTypeComma)
	nilRet := ""
	if retTypeComma != "" {
		nilRet = "nil, "
	}
	pn(`gensupport.SetOptions(c.urlParams_, opts...)`)
	pn(`res, err := c.doRequest("json")`)

	if retTypeComma != "" && !mapRetType {
		pn("if res != nil && res.StatusCode == http.StatusNotModified {")
		pn(" if res.Body != nil { res.Body.Close() }")
		pn(" return nil, &googleapi.Error{")
		pn("  Code: res.StatusCode,")
		pn("  Header: res.Header,")
		pn(" }")
		pn("}")
	}
	pn("if err != nil { return %serr }", nilRet)
	pn("defer googleapi.CloseBody(res)")
	pn("if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet)
	if meth.supportsMediaUpload() {
		pn(`rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))`)
		pn("if rx != nil {")
		pn(" rx.Client = c.s.client")
		pn(" rx.UserAgent = c.s.userAgent()")
		pn(" ctx := c.ctx_")
		pn(" if ctx == nil {")
		// TODO(mcgreevy): Require context when calling Media, or Do.
		pn("  ctx = context.TODO()")
		pn(" }")
		pn(" res, err = rx.Upload(ctx)")
		pn(" if err != nil { return %serr }", nilRet)
		pn(" defer res.Body.Close()")
		pn(" if err := googleapi.CheckResponse(res); err != nil { return %serr }", nilRet)
		pn("}")
	}
	if retTypeComma == "" {
		pn("return nil")
	} else {
		if mapRetType {
			pn("var ret %s", responseType(a, meth.m))
		} else {
			pn("ret := &%s{", responseTypeLiteral(a, meth.m))
			pn(" ServerResponse: googleapi.ServerResponse{")
			pn("  Header: res.Header,")
			pn("  HTTPStatusCode: res.StatusCode,")
			pn(" },")
			pn("}")
		}
		if a.needsDataWrapper() {
			pn("target := &struct {")
			pn("  Data %s `json:\"data\"`", responseType(a, meth.m))
			pn("}{ret}")
		} else {
			pn("target := &ret")
		}

		if meth.m.ID == "ml.projects.predict" {
			pn("var b bytes.Buffer")
			pn("if _, err := io.Copy(&b, res.Body); err != nil { return nil, err }")
			pn("if err := res.Body.Close(); err != nil { return nil, err }")
			pn("if err := json.NewDecoder(bytes.NewReader(b.Bytes())).Decode(target); err != nil { return nil, err }")
			pn("ret.Data = b.String()")
		} else {
			pn("if err := gensupport.DecodeResponse(target, res); err != nil { return nil, err }")
		}
		pn("return ret, nil")
	}

	bs, err := json.MarshalIndent(meth.m.JSONMap, "\t// ", "  ")
	if err != nil {
		panic(err)
	}
	pn("// %s\n", string(bs))
	pn("}")

	if ptg, rname, ok := meth.supportsPaging(); ok {
		// We can assume retType is non-empty.
		pn("")
		pn("// Pages invokes f for each page of results.")
		pn("// A non-nil error returned from f will halt the iteration.")
		pn("// The provided context supersedes any context provided to the Context method.")
		pn("func (c *%s) Pages(ctx context.Context, f func(%s) error) error {", callName, retType)
		pn(" c.ctx_ = ctx")
		pn(` defer %s  // reset paging to original point`, ptg.genDeferBody())
		pn(" for {")
		pn("  x, err := c.Do()")
		pn("  if err != nil { return err }")
		pn("  if err := f(x); err != nil { return err }")
		pn(`  if x.%s == "" { return nil }`, rname)
		pn(ptg.genSet("x." + rname))
		pn(" }")
		pn("}")
	}
}

// A Field provides methods that describe the characteristics of a Param or Property.
type Field interface {
	Default() string
	Enum() ([]string, bool)
	EnumDescriptions() []string
	UnfortunateDefault() bool
}

type Param struct {
	method        *Method
	p             *disco.Parameter
	callFieldName string // empty means to use the default
}

func (p *Param) Default() string {
	return p.p.Default
}

func (p *Param) Enum() ([]string, bool) {
	if e := p.p.Enums; e != nil {
		return e, true
	}
	return nil, false
}

func (p *Param) EnumDescriptions() []string {
	return p.p.EnumDescriptions
}

func (p *Param) UnfortunateDefault() bool {
	// We do not do anything special for Params with unfortunate defaults.
	return false
}

func (p *Param) GoType() string {
	typ, format := p.p.Type, p.p.Format
	if typ == "string" && strings.Contains(format, "int") && p.p.Location != "query" {
		panic("unexpected int parameter encoded as string, not in query: " + p.p.Name)
	}
	t, ok := simpleTypeConvert(typ, format)
	if !ok {
		panic("failed to convert parameter type " + fmt.Sprintf("type=%q, format=%q", typ, format))
	}
	return t
}

// goCallFieldName returns the name of this parameter's field in a
// method's "Call" struct.
func (p *Param) goCallFieldName() string {
	if p.callFieldName != "" {
		return p.callFieldName
	}
	return validGoIdentifer(p.p.Name)
}

// APIMethods returns top-level ("API-level") methods. They don't have an associated resource.
func (a *API) APIMethods() []*Method {
	meths := []*Method{}
	for _, m := range a.doc.Methods {
		meths = append(meths, &Method{
			api: a,
			r:   nil, // to be explicit
			m:   m,
		})
	}
	return meths
}

func resolveRelative(basestr, relstr string) string {
	u, err := url.Parse(basestr)
	if err != nil {
		panicf("Error parsing base URL %q: %v", basestr, err)
	}
	rel, err := url.Parse(relstr)
	if err != nil {
		panicf("Error parsing relative URL %q: %v", relstr, err)
	}
	u = u.ResolveReference(rel)
	return u.String()
}

func (meth *Method) NewArguments() *arguments {
	args := &arguments{
		method: meth,
		m:      make(map[string]*argument),
	}
	pnames := meth.m.ParameterOrder
	if len(pnames) == 0 {
		// No parameterOrder; collect required parameters and sort by name.
		for _, reqParam := range meth.grepParams(func(p *Param) bool { return p.p.Required }) {
			pnames = append(pnames, reqParam.p.Name)
		}
		sort.Strings(pnames)
	}
	for _, pname := range pnames {
		arg := meth.NewArg(pname, meth.NamedParam(pname))
		args.AddArg(arg)
	}
	if rs := meth.m.Request; rs != nil {
		args.AddArg(meth.NewBodyArg(rs))
	}
	return args
}

func (meth *Method) NewBodyArg(ds *disco.Schema) *argument {
	s := meth.api.schemaNamed(ds.RefSchema.Name)
	return &argument{
		goname:   validGoIdentifer(strings.ToLower(ds.Ref)),
		apiname:  "REQUEST",
		gotype:   "*" + s.GoName(),
		apitype:  ds.Ref,
		location: "body",
		schema:   s,
	}
}

func (meth *Method) NewArg(apiname string, p *Param) *argument {
	apitype := p.p.Type
	des := p.p.Description
	goname := validGoIdentifer(apiname) // but might be changed later, if conflicts
	if strings.Contains(des, "identifier") && !strings.HasSuffix(strings.ToLower(goname), "id") {
		goname += "id" // yay
		p.callFieldName = goname
	}
	gotype := mustSimpleTypeConvert(apitype, p.p.Format)
	if p.p.Repeated {
		gotype = "[]" + gotype
	}
	return &argument{
		apiname:  apiname,
		apitype:  apitype,
		goname:   goname,
		gotype:   gotype,
		location: p.p.Location,
	}
}

type argument struct {
	method           *Method
	schema           *Schema // Set if location == "body".
	apiname, apitype string
	goname, gotype   string
	location         string // "path", "query", "body"
}

func (a *argument) String() string {
	return a.goname + " " + a.gotype
}

func (a *argument) exprAsString(prefix string) string {
	switch a.gotype {
	case "[]string":
		log.Printf("TODO(bradfitz): only including the first parameter in path query.")
		return prefix + a.goname + `[0]`
	case "string":
		return prefix + a.goname
	case "integer", "int64":
		return "strconv.FormatInt(" + prefix + a.goname + ", 10)"
	case "uint64":
		return "strconv.FormatUint(" + prefix + a.goname + ", 10)"
	case "bool":
		return "strconv.FormatBool(" + prefix + a.goname + ")"
	}
	log.Panicf("unknown type: apitype=%q, gotype=%q", a.apitype, a.gotype)
	return ""
}

// arguments are the arguments that a method takes
type arguments struct {
	l      []*argument
	m      map[string]*argument
	method *Method
}

func (args *arguments) forLocation(loc string) []*argument {
	matches := make([]*argument, 0)
	for _, arg := range args.l {
		if arg.location == loc {
			matches = append(matches, arg)
		}
	}
	return matches
}

func (args *arguments) bodyArg() *argument {
	for _, arg := range args.l {
		if arg.location == "body" {
			return arg
		}
	}
	return nil
}

func (args *arguments) AddArg(arg *argument) {
	n := 1
	oname := arg.goname
	for {
		_, present := args.m[arg.goname]
		if !present {
			args.m[arg.goname] = arg
			args.l = append(args.l, arg)
			return
		}
		n++
		arg.goname = fmt.Sprintf("%s%d", oname, n)
	}
}

func (a *arguments) String() string {
	var buf bytes.Buffer
	for i, arg := range a.l {
		if i != 0 {
			buf.Write([]byte(", "))
		}
		buf.Write([]byte(arg.String()))
	}
	return buf.String()
}

var urlRE = regexp.MustCompile(`^http\S+$`)

func asComment(pfx, c string) string {
	var buf bytes.Buffer
	const maxLen = 70
	r := strings.NewReplacer(
		"\n", "\n"+pfx+"// ",
		"`\"", `"`,
		"\"`", `"`,
	)
	for len(c) > 0 {
		line := c
		if len(line) < maxLen {
			fmt.Fprintf(&buf, "%s// %s\n", pfx, r.Replace(line))
			break
		}
		// Don't break URLs.
		if !urlRE.MatchString(line[:maxLen]) {
			line = line[:maxLen]
		}
		si := strings.LastIndex(line, " ")
		if nl := strings.Index(line, "\n"); nl != -1 && nl < si {
			si = nl
		}
		if si != -1 {
			line = line[:si]
		}
		fmt.Fprintf(&buf, "%s// %s\n", pfx, r.Replace(line))
		c = c[len(line):]
		if si != -1 {
			c = c[1:]
		}
	}
	return buf.String()
}

func simpleTypeConvert(apiType, format string) (gotype string, ok bool) {
	// From http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1
	switch apiType {
	case "boolean":
		gotype = "bool"
	case "string":
		gotype = "string"
		switch format {
		case "int64", "uint64", "int32", "uint32":
			gotype = format
		}
	case "number":
		gotype = "float64"
	case "integer":
		gotype = "int64"
	case "any":
		gotype = "interface{}"
	}
	return gotype, gotype != ""
}

func mustSimpleTypeConvert(apiType, format string) string {
	if gotype, ok := simpleTypeConvert(apiType, format); ok {
		return gotype
	}
	panic(fmt.Sprintf("failed to simpleTypeConvert(%q, %q)", apiType, format))
}

func responseType(api *API, m *disco.Method) string {
	if m.Response == nil {
		return ""
	}
	ref := m.Response.Ref
	if ref != "" {
		if s := api.schemas[ref]; s != nil {
			return s.GoReturnType()
		}
		return "*" + ref
	}
	return ""
}

// Strips the leading '*' from a type name so that it can be used to create a literal.
func responseTypeLiteral(api *API, m *disco.Method) string {
	v := responseType(api, m)
	if strings.HasPrefix(v, "*") {
		return v[1:]
	}
	return v
}

// initialCap returns the identifier with a leading capital letter.
// it also maps "foo-bar" to "FooBar".
func initialCap(ident string) string {
	if ident == "" {
		panic("blank identifier")
	}
	return depunct(ident, true)
}

func validGoIdentifer(ident string) string {
	id := depunct(ident, false)
	switch id {
	case "break", "default", "func", "interface", "select",
		"case", "defer", "go", "map", "struct",
		"chan", "else", "goto", "package", "switch",
		"const", "fallthrough", "if", "range", "type",
		"continue", "for", "import", "return", "var":
		return id + "_"
	}
	return id
}

// depunct removes '-', '.', '$', '/', '_' from identifers, making the
// following character uppercase. Multiple '_' are preserved.
func depunct(ident string, needCap bool) string {
	var buf bytes.Buffer
	preserve_ := false
	for i, c := range ident {
		if c == '_' {
			if preserve_ || strings.HasPrefix(ident[i:], "__") {
				preserve_ = true
			} else {
				needCap = true
				continue
			}
		} else {
			preserve_ = false
		}
		if c == '-' || c == '.' || c == '$' || c == '/' {
			needCap = true
			continue
		}
		if needCap {
			c = unicode.ToUpper(c)
			needCap = false
		}
		buf.WriteByte(byte(c))
	}
	return buf.String()

}

func addFieldValueComments(p func(format string, args ...interface{}), field Field, indent string, blankLine bool) {
	var lines []string

	if enum, ok := field.Enum(); ok {
		desc := field.EnumDescriptions()
		lines = append(lines, asComment(indent, "Possible values:"))
		defval := field.Default()
		for i, v := range enum {
			more := ""
			if v == defval {
				more = " (default)"
			}
			if len(desc) > i && desc[i] != "" {
				more = more + " - " + desc[i]
			}
			lines = append(lines, asComment(indent, `  "`+v+`"`+more))
		}
	} else if field.UnfortunateDefault() {
		lines = append(lines, asComment("\t", fmt.Sprintf("Default: %s", field.Default())))
	}
	if blankLine && len(lines) > 0 {
		p(indent + "//\n")
	}
	for _, l := range lines {
		p("%s", l)
	}
}
