// 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/ioutil"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"unicode"
)

// goGenVersion is the version of the Go code generator
const goGenVersion = "0.5"

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", "https://www.googleapis.com/discovery/v1/apis", "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).")
	googleAPIPkg = flag.String("googleapi_pkg", "google.golang.org/api/googleapi", "Go package path of the 'googleapi' support package.")
	contextPkg   = flag.String("context_pkg", "golang.org/x/net/context", "Go package path of the 'context' support package.")
)

// API represents an API to generate, as well as its state while it's
// generating.
type API struct {
	ID            string `json:"id"`
	Name          string `json:"name"`
	Version       string `json:"version"`
	Title         string `json:"title"`
	DiscoveryLink string `json:"discoveryLink"` // relative
	RootURL       string `json:"rootUrl"`
	ServicePath   string `json:"servicePath"`
	Preferred     bool   `json:"preferred"`

	m map[string]interface{}

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

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

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

type AllAPIs struct {
	Items []*API `json:"items"`
}

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 {
			errors = append(errors, &generateError{api, err})
			continue
		}
		if *build {
			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.Printf(ce.Error())
		}
		os.Exit(1)
	}
}

func (a *API) want() bool {
	if strings.Contains(a.ID, "buzz") {
		// R.I.P.
		return false
	}
	if strings.Contains(a.ID, "fusiontables") {
		// TODO(bradfitz): broken codegen.
		return false
	}
	return *apiToGenerate == "*" || *apiToGenerate == a.ID
}

func getAPIs() []*API {
	if *jsonFile != "" {
		return getAPIsFromFile()
	}
	var all AllAPIs
	disco := slurpURL(*apisURL)
	if err := json.Unmarshal(disco, &all); err != nil {
		log.Fatalf("error decoding JSON in %s: %v", apisURL, err)
	}
	if !*publicOnly && *apiToGenerate != "*" {
		parts := strings.SplitN(*apiToGenerate, ":", 2)
		apiName := parts[0]
		apiVersion := parts[1]
		all.Items = append(all.Items, &API{
			ID:            *apiToGenerate,
			Name:          apiName,
			Version:       apiVersion,
			DiscoveryLink: fmt.Sprintf("./apis/%s/%s/rest", apiName, apiVersion),
		})
	}
	return all.Items
}

// 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)
	}
	a := &API{
		forceJSON: jsonBytes,
	}
	if err := json.Unmarshal(jsonBytes, a); err != nil {
		return nil, fmt.Errorf("Decoding JSON in %s: %v", file, err)
	}
	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
	}
	return ioutil.WriteFile(file, contents, 0644)
}

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

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

func slurpURL(urlStr string) []byte {
	diskFile := filepath.Join(os.TempDir(), "google-api-cache-"+url.QueryEscape(urlStr))
	if *useCache {
		bs, err := ioutil.ReadFile(diskFile)
		if err == nil && len(bs) > 0 {
			return bs
		}
	}

	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)
	}
	bs, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Error reading body of URL %s: %v", urlStr, err)
	}
	if *useCache {
		if err := ioutil.WriteFile(diskFile, bs, 0666); err != nil {
			log.Printf("Warning: failed to write JSON of %s to disk file %s: %v", urlStr, diskFile, 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
}

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 (a *API) SourceDir() string {
	if *genDir == "" {
		paths := filepath.SplitList(os.Getenv("GOPATH"))
		if len(paths) > 0 && paths[0] != "" {
			*genDir = filepath.Join(paths[0], "src", "google.golang.org", "api")
		}
	}
	return filepath.Join(*genDir, a.Package(), a.Version)
}

func (a *API) DiscoveryURL() string {
	if a.DiscoveryLink == "" {
		log.Fatalf("API %s has no DiscoveryLink", a.ID)
	}
	base, _ := url.Parse(*apisURL)
	u, err := base.Parse(a.DiscoveryLink)
	if err != nil {
		log.Fatalf("API %s has bogus DiscoveryLink %s: %v", a.ID, a.DiscoveryLink, err)
	}
	return u.String()
}

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

func (a *API) Target() string {
	return fmt.Sprintf("google.golang.org/api/%s/%s", a.Package(), a.Version)
}

// 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 {
	if a.RootURL != "" {
		return a.RootURL + a.ServicePath
	}
	return resolveRelative(*apisURL, jstr(a.m, "basePath"))
}

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

func (a *API) jsonBytes() []byte {
	if v := a.forceJSON; v != nil {
		return v
	}
	return slurpURL(a.DiscoveryURL())
}

func (a *API) WriteGeneratedCode() error {
	outdir := a.SourceDir()
	err := os.MkdirAll(outdir, 0755)
	if err != nil {
		return fmt.Errorf("failed to Mkdir %s: %v", outdir, err)
	}

	pkg := a.Package()
	writeFile(filepath.Join(outdir, a.Package()+"-api.json"), a.jsonBytes())

	genfilename := *output
	if genfilename == "" {
		genfilename = filepath.Join(outdir, pkg+"-gen.go")
	}

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

var docsLink string

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

	a.m = make(map[string]interface{})
	m := a.m
	jsonBytes := a.jsonBytes()
	err := json.Unmarshal(jsonBytes, &a.m)
	if err != nil {
		return nil, err
	}

	// Buffer the output in memory, for gofmt'ing later in the defer.
	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...)
	}

	p, pn := a.p, a.pn
	reslist := a.Resources(a.m, "")

	p("// Package %s provides access to the %s.\n", pkg, jstr(m, "title"))
	docsLink = jstr(m, "documentationLink")
	if docsLink != "" {
		p("//\n")
		p("// See %s\n", docsLink)
	}
	p("//\n// Usage example:\n")
	p("//\n")
	p("//   import %q\n", a.Target())
	p("//   ...\n")
	p("//   %sService, err := %s.New(oauthHttpClient)\n", pkg, pkg)

	p("package %s\n", pkg)
	p("\n")
	p("import (\n")
	for _, pkg := range []string{
		"bytes",
		*googleAPIPkg,
		"encoding/json",
		"errors",
		"fmt",
		"io",
		"net/http",
		"net/url",
		"strconv",
		"strings",
		*contextPkg,
	} {
		p("\t%q\n", pkg)
	}
	p(")\n\n")
	pn("// 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 _ = googleapi.Version")
	pn("var _ = errors.New")
	pn("var _ = strings.Replace")
	pn("var _ = context.Background")
	pn("")
	pn("const apiId = %q", jstr(m, "id"))
	pn("const apiName = %q", jstr(m, "name"))
	pn("const apiVersion = %q", jstr(m, "version"))
	p("const basePath = %q\n", a.apiBaseURL())
	p("\n")

	a.generateScopeConstants()

	a.GetName("New") // ignore return value; we're the first caller
	pn("func New(client *http.Client) (*Service, error) {")
	pn("if client == nil { return nil, errors.New(\"client is nil\") }")
	pn("s := &Service{client: client, BasePath: basePath}")
	for _, res := range reslist { // add top level resources.
		pn("s.%s = New%s(s)", res.GoField(), res.GoType())
	}
	pn("return s, nil")
	pn("}")

	a.GetName("Service") // ignore return value; no user-defined names yet
	p("\ntype Service struct {\n")
	p("\tclient *http.Client\n")
	p("\tBasePath string // API endpoint base URL\n")

	for _, res := range reslist {
		p("\n\t%s\t*%s\n", res.GoField(), res.GoType())
	}
	p("}\n")

	for _, res := range reslist {
		res.generateType()
	}

	a.PopulateSchemas()

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

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

	for _, res := range reslist {
		res.generateMethods()
	}

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

func (a *API) generateScopeConstants() {
	auth := jobj(a.m, "auth")
	if auth == nil {
		return
	}
	oauth2 := jobj(auth, "oauth2")
	if oauth2 == nil {
		return
	}
	scopes := jobj(oauth2, "scopes")
	if scopes == nil || len(scopes) == 0 {
		return
	}

	a.p("// OAuth2 scopes used by this API.\n")
	a.p("const (\n")
	n := 0
	for _, scopeName := range sortedKeys(scopes) {
		mi := scopes[scopeName]
		if n > 0 {
			a.p("\n")
		}
		n++
		ident := scopeIdentifierFromURL(scopeName)
		if des := jstr(mi.(map[string]interface{}), "description"); des != "" {
			a.p("%s", asComment("\t", des))
		}
		a.p("\t%s = %q\n", ident, scopeName)
	}
	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
}

type Schema struct {
	api *API
	m   map[string]interface{} // original JSON map

	typ *Type // lazily populated by Type

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

type Property struct {
	s       *Schema                // property of which schema
	apiName string                 // the native API-defined name of this property
	m       map[string]interface{} // original JSON map

	typ *Type // lazily populated by Type
}

func (p *Property) Type() *Type {
	if p.typ == nil {
		p.typ = &Type{api: p.s.api, m: p.m}
	}
	return p.typ
}

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

func (p *Property) APIName() string {
	return p.apiName
}

func (p *Property) Description() string {
	return jstr(p.m, "description")
}

type Type struct {
	m   map[string]interface{} // JSON map containing key "type" and maybe "items", "properties"
	api *API
}

func (t *Type) apiType() string {
	// Note: returns "" on reference types
	if t, ok := t.m["type"].(string); ok {
		return t
	}
	return ""
}

func (t *Type) apiTypeFormat() string {
	if f, ok := t.m["format"].(string); ok {
		return f
	}
	return ""
}

func (t *Type) isIntAsString() bool {
	return t.apiType() == "string" && strings.Contains(t.apiTypeFormat(), "int")
}

func (t *Type) asSimpleGoType() (goType string, ok bool) {
	return simpleTypeConvert(t.apiType(), t.apiTypeFormat())
}

func (t *Type) String() string {
	return fmt.Sprintf("[type=%q, map=%s]", t.apiType(), prettyJSON(t.m))
}

func (t *Type) AsGo() string {
	if t, ok := t.asSimpleGoType(); ok {
		return t
	}
	if at, ok := t.ArrayType(); ok {
		if at.apiType() == "string" {
			switch at.apiTypeFormat() {
			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"
			default:
				return "[]" + at.AsGo()
			}
		}
		return "[]" + at.AsGo()
	}
	if ref, ok := t.Reference(); ok {
		s := t.api.schemas[ref]
		if s == nil {
			panic(fmt.Sprintf("in Type.AsGo(), failed to find referenced type %q for %s",
				ref, prettyJSON(t.m)))
		}
		return s.Type().AsGo()
	}
	if typ, ok := t.MapType(); ok {
		return typ
	}
	if t.IsStruct() {
		if apiName, ok := t.m["_apiName"].(string); ok {
			s := t.api.schemas[apiName]
			if s == nil {
				panic(fmt.Sprintf("in Type.AsGo, _apiName of %q didn't point to a valid schema; json: %s",
					apiName, prettyJSON(t.m)))
			}
			if v := jobj(s.m, "variant"); v != nil {
				return s.GoName()
			}
			return "*" + s.GoName()
		}
		panic("in Type.AsGo, no _apiName found for struct type " + prettyJSON(t.m))
	}
	panic("unhandled Type.AsGo for " + prettyJSON(t.m))
}

func (t *Type) IsSimple() bool {
	_, ok := simpleTypeConvert(t.apiType(), t.apiTypeFormat())
	return ok
}

func (t *Type) IsStruct() bool {
	return t.apiType() == "object"
}

func (t *Type) Reference() (apiName string, ok bool) {
	apiName = jstr(t.m, "$ref")
	ok = apiName != ""
	return
}

func (t *Type) IsMap() bool {
	_, ok := t.MapType()
	return ok
}

// MapType checks if the current node is a map and if true, it returns the Go type for the map, such as map[string]string.
func (t *Type) MapType() (typ string, ok bool) {
	props := jobj(t.m, "additionalProperties")
	if props == nil {
		return "", false
	}
	s := jstr(props, "type")
	if s == "string" {
		return "map[string]string", true
	}
	if s != "array" {
		if s == "" { // Check for reference
			s = jstr(props, "$ref")
			if s != "" {
				return "map[string]" + s, true
			}
		}
		log.Printf("Warning: found map to type %q which is not implemented yet.", s)
		return "", false
	}
	items := jobj(props, "items")
	if items == nil {
		return "", false
	}
	s = jstr(items, "type")
	if s != "string" {
		if s == "" { // Check for reference
			s = jstr(items, "$ref")
			if s != "" {
				return "map[string][]" + s, true
			}
		}
		log.Printf("Warning: found map of arrays of type %q which is not implemented yet.", s)
		return "", false
	}
	return "map[string][]string", true
}

func (t *Type) IsReference() bool {
	return jstr(t.m, "$ref") != ""
}

func (t *Type) ReferenceSchema() (s *Schema, ok bool) {
	apiName, ok := t.Reference()
	if !ok {
		return
	}

	s = t.api.schemas[apiName]
	if s == nil {
		panicf("failed to find t.api.schemas[%q] while resolving reference",
			apiName)
	}
	return s, true
}

func (t *Type) ArrayType() (elementType *Type, ok bool) {
	if t.apiType() != "array" {
		return
	}
	items := jobj(t.m, "items")
	if items == nil {
		panicf("can't handle array type missing its 'items' key. map is %#v", t.m)
	}
	return &Type{api: t.api, m: items}, true
}

func (s *Schema) Type() *Type {
	if s.typ == nil {
		s.typ = &Type{api: s.api, m: s.m}
	}
	return s.typ
}

func (s *Schema) properties() []*Property {
	if !s.Type().IsStruct() {
		panic("called properties on non-object schema")
	}
	pl := []*Property{}
	propMap := jobj(s.m, "properties")
	for _, name := range sortedKeys(propMap) {
		m := propMap[name].(map[string]interface{})
		pl = append(pl, &Property{
			s:       s,
			m:       m,
			apiName: name,
		})
	}
	return pl
}

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

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

	if s.Type().IsStruct() {
		for _, p := range s.properties() {
			if p.Type().IsSimple() || p.Type().IsMap() {
				continue
			}
			if at, ok := p.Type().ArrayType(); ok {
				if at.IsSimple() || at.IsReference() {
					continue
				}
				subApiName := fmt.Sprintf("%s.%s", s.apiName, p.apiName)
				if at.IsStruct() {
					addSubStruct(subApiName, at) // was p.Type()?
					continue
				}
				if _, ok := at.ArrayType(); ok {
					addSubStruct(subApiName, at)
					continue
				}
				panicf("Unknown property array type for %q: %s", subApiName, at)
				continue
			}
			subApiName := fmt.Sprintf("%s.%s", s.apiName, p.apiName)
			if p.Type().IsStruct() {
				addSubStruct(subApiName, p.Type())
				continue
			}
			if p.Type().IsReference() {
				continue
			}
			panicf("Unknown type for %q: %s", subApiName, p.Type())
		}
		return
	}

	if at, ok := s.Type().ArrayType(); ok {
		if at.IsSimple() || at.IsReference() {
			return
		}
		subApiName := fmt.Sprintf("%s.Item", s.apiName)

		if at.IsStruct() {
			addSubStruct(subApiName, at)
			return
		}
		if at, ok := at.ArrayType(); ok {
			if at.IsSimple() || at.IsReference() {
				return
			}
			addSubStruct(subApiName, at)
			return
		}
		panicf("Unknown array type for %q: %s", subApiName, at)
		return
	}

	if s.Type().IsSimple() || s.Type().IsReference() {
		return
	}

	fmt.Fprintf(os.Stderr, "in populateSubSchemas, schema is: %s", prettyJSON(s.m))
	panicf("populateSubSchemas: unsupported type for schema %q", s.apiName)
	panic("unreachable")
}

// 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 name, ok := s.Type().MapType(); ok {
			s.goName = name
		} else {
			s.goName = s.api.GetName(initialCap(s.apiName))
		}
	}
	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.Type().IsMap() {
			s.goReturnType = s.GoName()
		} else {
			s.goReturnType = "*" + s.GoName()
		}
	}
	return s.goReturnType
}

func (s *Schema) writeSchemaCode(api *API) {
	if s.Type().IsStruct() && !s.Type().IsMap() {
		s.writeSchemaStruct(api)
		return
	}

	if _, ok := s.Type().ArrayType(); ok {
		log.Printf("TODO writeSchemaCode for arrays for %s", s.GoName())
		return
	}

	if destSchema, ok := s.Type().ReferenceSchema(); ok {
		// Convert it to a struct using embedding.
		s.api.p("\ntype %s struct {\n", s.GoName())
		s.api.p("\t%s\n", destSchema.GoName())
		s.api.p("}\n")
		return
	}

	if s.Type().IsSimple() {
		apitype := jstr(s.m, "type")
		typ := mustSimpleTypeConvert(apitype, jstr(s.m, "format"))
		s.api.p("\ntype %s %s\n", s.GoName(), typ)
		return
	}

	if s.Type().IsMap() {
		return
	}

	fmt.Fprintf(os.Stderr, "in writeSchemaCode, schema is: %s", prettyJSON(s.m))
	panicf("writeSchemaCode: unsupported type for schema %q", s.apiName)
}

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

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

	// Write out helper methods to convert each possible variant.
	for _, m := range jobjlist(v, "map") {
		val := jstr(m, "type_value")
		reftype := jstr(m, "$ref")
		if val == "" && reftype == "" {
			log.Printf("TODO variant %s ref %s not yet supported.", val, reftype)
			continue
		}

		_, ok := api.schemas[reftype]
		if !ok {
			log.Printf("TODO variant %s ref %s not yet supported.", val, reftype)
			continue
		}

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

func (s *Schema) writeSchemaStruct(api *API) {
	if v := jobj(s.m, "variant"); v != nil {
		s.writeVariant(api, v)
		return
	}
	// TODO: description
	s.api.p("\ntype %s struct {\n", s.GoName())
	for i, p := range s.properties() {
		if i > 0 {
			s.api.p("\n")
		}
		pname := p.GoName()
		if des := p.Description(); des != "" {
			s.api.p("%s", asComment("\t", fmt.Sprintf("%s: %s", pname, des)))
		}
		var extraOpt string
		if p.Type().isIntAsString() {
			extraOpt += ",string"
		}
		s.api.p("\t%s %s `json:\"%s,omitempty%s\"`\n", pname, p.Type().AsGo(), p.APIName(), extraOpt)
	}
	s.api.p("}\n")
}

// 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() {
	m := jobj(a.m, "schemas")
	if a.schemas != nil {
		panic("")
	}
	a.schemas = make(map[string]*Schema)
	for name, mi := range m {
		s := &Schema{
			api:     a,
			apiName: name,
			m:       mi.(map[string]interface{}),
		}

		// And a little gross hack, so a map alone is good
		// enough to get its apiName:
		s.m["_apiName"] = name

		a.schemas[name] = s
		err := s.populateSubSchemas()
		if err != nil {
			panicf("Error populating schema with API name %q: %v", name, err)
		}
	}
}

type Resource struct {
	api       *API
	name      string
	parent    string
	m         map[string]interface{}
	resources []*Resource
}

func (r *Resource) generateType() {
	p, pn := r.api.p, r.api.pn
	t := r.GoType()
	pn(fmt.Sprintf("func New%s(s *Service) *%s {", t, t))
	pn("rs := &%s{s : s}", t)
	for _, res := range r.resources {
		pn("rs.%s = New%s(s)", res.GoField(), res.GoType())
	}
	pn("return rs")
	pn("}")

	p("\ntype %s struct {\n", t)
	p("\ts *Service\n")
	for _, res := range r.resources {
		p("\n\t%s\t*%s\n", res.GoField(), res.GoType())
	}
	p("}\n")

	for _, res := range r.resources {
		res.generateType()
	}
}

func (r *Resource) generateMethods() {
	for _, meth := range r.Methods() {
		meth.generateCode()
	}
	for _, res := range r.resources {
		res.generateMethods()
	}
}

func (r *Resource) GoField() string {
	return initialCap(r.name)
}

func (r *Resource) GoType() string {
	return initialCap(fmt.Sprintf("%s.%s", r.parent, r.name)) + "Service"
}

func (r *Resource) Methods() []*Method {
	ms := []*Method{}

	methMap := jobj(r.m, "methods")
	for _, mname := range sortedKeys(methMap) {
		mi := methMap[mname]
		ms = append(ms, &Method{
			api:  r.api,
			r:    r,
			name: mname,
			m:    mi.(map[string]interface{}),
		})
	}
	return ms
}

type Method struct {
	api  *API
	r    *Resource // or nil if a API-level (top-level) method
	name string
	m    map[string]interface{} // original JSON

	params []*Param // all Params, of each type, lazily set by first access to Parameters
}

func (m *Method) Id() string {
	return jstr(m.m, "id")
}

func (m *Method) supportsMediaUpload() bool {
	return jobj(m.m, "mediaUpload") != nil
}

func (m *Method) mediaUploadPath() string {
	return jstr(jobj(jobj(jobj(m.m, "mediaUpload"), "protocols"), "simple"), "path")
}

func (m *Method) Params() []*Param {
	if m.params == nil {
		paramMap := jobj(m.m, "parameters")
		for _, name := range sortedKeys(paramMap) {
			mi := paramMap[name]
			pm := mi.(map[string]interface{})
			m.params = append(m.params, &Param{
				name:   name,
				m:      pm,
				method: m,
			})
		}
	}
	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.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.IsRequired()
	})
}

func (m *Method) RequiredRepeatedQueryParams() []*Param {
	return m.grepParams(func(p *Param) bool {
		return p.IsRequired() && p.IsRepeated() && p.Location() == "query"
	})
}

func (m *Method) RequiredQueryParams() []*Param {
	return m.grepParams(func(p *Param) bool {
		return p.IsRequired() && !p.IsRepeated() && p.Location() == "query"
	})
}

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())

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

	args := meth.NewArguments()
	methodName := initialCap(meth.name)
	prefix := ""
	if res != nil {
		prefix = initialCap(fmt.Sprintf("%s.%s", res.parent, res.name))
	}
	callName := a.GetName(prefix + methodName + "Call")

	p("\ntype %s struct {\n", callName)
	p("\ts *Service\n")
	for _, arg := range args.l {
		p("\t%s %s\n", arg.goname, arg.gotype)
	}
	p("\topt_ map[string]interface{}\n")
	if meth.supportsMediaUpload() {
		p("\tmedia_     io.Reader\n")
		p("\tresumable_ googleapi.SizeReaderAt\n")
		p("\tmediaType_ string\n")
		p("\tctx_       context.Context\n")
		p("\tprotocol_  string\n")
	}
	p("}\n")

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

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

	p("\tc := &%s{s: %s, opt_: make(map[string]interface{})}\n", callName, servicePtr)
	for _, arg := range args.l {
		p("\tc.%s = %s\n", arg.goname, arg.goname)
	}
	p("\treturn c\n")
	p("}\n")

	for _, opt := range meth.OptParams() {
		setter := initialCap(opt.name)
		des := jstr(opt.m, "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.name, des)))
		np := new(namePool)
		np.Get("c") // take the receiver's name
		paramName := np.Get(validGoIdentifer(opt.name))
		p("func (c *%s) %s(%s %s) *%s {\n", callName, setter, paramName, opt.GoType(), callName)
		p("c.opt_[%q] = %s\n", opt.name, paramName)
		p("return c\n")
		p("}\n")
	}

	if meth.supportsMediaUpload() {
		pn("\n// Media specifies the media to upload in a single chunk.")
		pn("// At most one of Media and ResumableMedia may be set.")
		pn("func (c *%s) Media(r io.Reader) *%s {", callName, callName)
		pn("c.media_ = r")
		pn(`c.protocol_ = "multipart"`)
		pn("return c")
		pn("}")
		pn("\n// ResumableMedia specifies the media to upload in chunks and can be cancelled with ctx.")
		pn("// At most one of Media and ResumableMedia may be set.")
		pn(`// mediaType identifies the MIME media type of the upload, such as "image/png".`)
		pn(`// If mediaType is "", it will be auto-detected.`)
		pn("func (c *%s) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *%s {", callName, callName)
		pn("c.ctx_ = ctx")
		pn("c.resumable_ = io.NewSectionReader(r, 0, size)")
		pn("c.mediaType_ = mediaType")
		pn(`c.protocol_ = "resumable"`)
		pn("return c")
		pn("}")
		pn("\n// ProgressUpdater provides a callback function that will be called after every chunk.")
		pn("// It should be a low-latency function in order to not slow down the upload operation.")
		pn("// This should only be called when using ResumableMedia (as opposed to Media).")
		pn("func (c *%s) ProgressUpdater(pu googleapi.ProgressUpdater) *%s {", callName, callName)
		pn(`c.opt_["progressUpdater"] = pu`)
		pn("return c")
		pn("}")
	}

	pn("\n// Fields allows partial responses to be retrieved.")
	pn("// See https://developers.google.com/gdata/docs/2.0/basics#PartialResponse")
	pn("// for more information.")
	pn("func (c *%s) Fields(s ...googleapi.Field) *%s {", callName, callName)
	pn(`c.opt_["fields"] = googleapi.CombineFields(s)`)
	pn("return c")
	pn("}")

	pn("\nfunc (c *%s) Do() (%serror) {", callName, retTypeComma)

	nilRet := ""
	if retTypeComma != "" {
		nilRet = "nil, "
	}
	pn("var body io.Reader = nil")
	hasContentType := false
	httpMethod := jstr(meth.m, "httpMethod")
	if ba := args.bodyArg(); ba != nil && httpMethod != "GET" {
		style := "WithoutDataWrapper"
		if a.needsDataWrapper() {
			style = "WithDataWrapper"
		}
		pn("body, err := googleapi.%s.JSONReader(c.%s)", style, ba.goname)
		pn("if err != nil { return %serr }", nilRet)
		pn(`ctype := "application/json"`)
		hasContentType = true
	}
	pn("params := make(url.Values)")
	// Set this first. if they override it, though, might be gross.  We don't expect
	// XML replies elsewhere.  TODO(bradfitz): hide this option in the generated code?
	pn(`params.Set("alt", "json")`)
	for _, p := range meth.RequiredQueryParams() {
		pn("params.Set(%q, fmt.Sprintf(\"%%v\", c.%s))", p.name, p.goCallFieldName())
	}
	for _, p := range meth.RequiredRepeatedQueryParams() {
		pn("for _, v := range c.%s { params.Add(%q, fmt.Sprintf(\"%%v\", v)) }",
			p.name, p.name)
	}
	opts := meth.OptParams()
	opts = append(opts, &Param{name: "fields"})
	for _, p := range opts {
		pn("if v, ok := c.opt_[%q]; ok { params.Set(%q, fmt.Sprintf(\"%%v\", v)) }",
			p.name, p.name)
	}

	p("urls := googleapi.ResolveRelative(c.s.BasePath, %q)\n", jstr(meth.m, "path"))
	if meth.supportsMediaUpload() {
		pn("var progressUpdater_ googleapi.ProgressUpdater")
		pn("if v, ok := c.opt_[\"progressUpdater\"]; ok {")
		pn(" if pu, ok := v.(googleapi.ProgressUpdater); ok {")
		pn("  progressUpdater_ = pu")
		pn(" }")
		pn("}")
		pn("if c.media_ != nil || c.resumable_ != 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(`params.Set("uploadType", c.protocol_)`)
		pn("}")
	}
	pn("urls += \"?\" + params.Encode()")
	if meth.supportsMediaUpload() && httpMethod != "GET" {
		if !hasContentType { // Support mediaUpload but no ctype set.
			pn("body = new(bytes.Buffer)")
			pn(`ctype := "application/json"`)
			hasContentType = true
		}
		pn(`if c.protocol_ != "resumable" {`)
		pn(`  var cancel func()`)
		pn("  cancel, _ = googleapi.ConditionallyIncludeMedia(c.media_, &body, &ctype)")
		pn("  if cancel != nil { defer cancel() }")
		pn("}")
	}
	pn("req, _ := http.NewRequest(%q, urls, body)", httpMethod)
	// 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(`})`)
	} else {
		// Just call SetOpaque since we aren't calling Expand
		pn(`googleapi.SetOpaque(req.URL)`)
	}

	if meth.supportsMediaUpload() {
		pn(`if c.protocol_ == "resumable" {`)
		pn(" req.ContentLength = 0")
		pn(` if c.mediaType_ == "" {`)
		pn("  c.mediaType_ = googleapi.DetectMediaType(c.resumable_)")
		pn(" }")
		pn(` req.Header.Set("X-Upload-Content-Type", c.mediaType_)`)
		pn(" req.Body = nil")
		pn("} else {")
		pn(` req.Header.Set("Content-Type", ctype)`)
		pn("}")
	} else if hasContentType {
		pn(`req.Header.Set("Content-Type", ctype)`)
	}
	pn(`req.Header.Set("User-Agent", "google-api-go-client/` + goGenVersion + `")`)
	pn("res, err := c.s.client.Do(req);")
	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(`if c.protocol_ == "resumable" {`)
		pn(` loc := res.Header.Get("Location")`)
		pn(" rx := &googleapi.ResumableUpload{")
		pn("  Client:        c.s.client,")
		pn("  URI:           loc,")
		pn("  Media:         c.resumable_,")
		pn("  MediaType:     c.mediaType_,")
		pn("  ContentLength: c.resumable_.Size(),")
		pn("  Callback:      progressUpdater_,")
		pn(" }")
		pn(" res, err = rx.Upload(c.ctx_)")
		pn(" if err != nil { return %serr }", nilRet)
		pn(" defer res.Body.Close()")
		pn("}")
	}
	if retTypeComma == "" {
		pn("return nil")
	} else {
		pn("var ret %s", responseType(a, meth.m))
		pn("if err := json.NewDecoder(res.Body).Decode(&ret); err != nil { return nil, err }")
		pn("return ret, nil")
	}

	bs, _ := json.MarshalIndent(meth.m, "\t// ", "  ")
	pn("// %s\n", string(bs))
	pn("}")
}

type Param struct {
	method        *Method
	name          string
	m             map[string]interface{}
	callFieldName string // empty means to use the default
}

func (p *Param) IsRequired() bool {
	v, _ := p.m["required"].(bool)
	return v
}

func (p *Param) IsRepeated() bool {
	v, _ := p.m["repeated"].(bool)
	return v
}

func (p *Param) Location() string {
	return p.m["location"].(string)
}

func (p *Param) GoType() string {
	typ, format := jstr(p.m, "type"), jstr(p.m, "format")
	if typ == "string" && strings.Contains(format, "int") && p.Location() != "query" {
		panic("unexpected int parameter encoded as string, not in query: " + 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.name)
}

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

func (a *API) Resources(m map[string]interface{}, p string) []*Resource {
	res := []*Resource{}
	resMap := jobj(m, "resources")
	for _, rname := range sortedKeys(resMap) {
		rmi := resMap[rname]
		rm := rmi.(map[string]interface{})
		res = append(res, &Resource{a, rname, p, rm, a.Resources(rm, fmt.Sprintf("%s.%s", p, rname))})
	}
	return res
}

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() (args *arguments) {
	args = &arguments{
		method: meth,
		m:      make(map[string]*argument),
	}
	po, ok := meth.m["parameterOrder"].([]interface{})
	if ok {
		for _, poi := range po {
			pname := poi.(string)
			arg := meth.NewArg(pname, meth.NamedParam(pname))
			args.AddArg(arg)
		}
	}
	if ro := jobj(meth.m, "request"); ro != nil {
		args.AddArg(meth.NewBodyArg(ro))
	}
	return
}

func (meth *Method) NewBodyArg(m map[string]interface{}) *argument {
	reftype := jstr(m, "$ref")
	return &argument{
		goname:   validGoIdentifer(strings.ToLower(reftype)),
		apiname:  "REQUEST",
		gotype:   "*" + reftype,
		apitype:  reftype,
		location: "body",
	}
}

func (meth *Method) NewArg(apiname string, p *Param) *argument {
	m := p.m
	apitype := jstr(m, "type")
	des := jstr(m, "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, jstr(m, "format"))
	if p.IsRepeated() {
		gotype = "[]" + gotype
	}
	return &argument{
		apiname:  apiname,
		apitype:  apitype,
		goname:   goname,
		gotype:   gotype,
		location: jstr(m, "location"),
	}
}

type argument struct {
	method           *Method
	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)"
	}
	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()
}

func asComment(pfx, c string) string {
	var buf bytes.Buffer
	const maxLen = 70
	removeNewlines := func(s string) string {
		return strings.Replace(s, "\n", "\n"+pfx+"// ", -1)
	}
	for len(c) > 0 {
		line := c
		if len(line) < maxLen {
			fmt.Fprintf(&buf, "%s// %s\n", pfx, removeNewlines(line))
			break
		}
		line = line[:maxLen]
		si := strings.LastIndex(line, " ")
		if si != -1 {
			line = line[:si]
		}
		fmt.Fprintf(&buf, "%s// %s\n", pfx, removeNewlines(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 (a *API) goTypeOfJsonObject(outerName, memberName string, m map[string]interface{}) (string, error) {
	apitype := jstr(m, "type")
	switch apitype {
	case "array":
		items := jobj(m, "items")
		if items == nil {
			return "", errors.New("no items but type was array")
		}
		if ref := jstr(items, "$ref"); ref != "" {
			return "[]*" + ref, nil // TODO: wrong; delete this whole function
		}
		if atype := jstr(items, "type"); atype != "" {
			return "[]" + mustSimpleTypeConvert(atype, jstr(items, "format")), nil
		}
		return "", errors.New("unsupported 'array' type")
	case "object":
		return "*" + outerName + "_" + memberName, nil
		//return "", os.NewError("unsupported 'object' type")
	}
	return mustSimpleTypeConvert(apitype, jstr(m, "format")), nil
}

func responseType(api *API, m map[string]interface{}) string {
	ro := jobj(m, "response")
	if ro != nil {
		if ref := jstr(ro, "$ref"); ref != "" {
			if s := api.schemas[ref]; s != nil {
				return s.GoReturnType()
			}
			return "*" + ref
		}
	}
	return ""
}

// 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
func depunct(ident string, needCap bool) string {
	var buf bytes.Buffer
	for _, c := range ident {
		if c == '-' || c == '.' || c == '$' || c == '/' {
			needCap = true
			continue
		}
		if needCap {
			c = unicode.ToUpper(c)
			needCap = false
		}
		buf.WriteByte(byte(c))
	}
	return buf.String()

}

func prettyJSON(m map[string]interface{}) string {
	bs, err := json.MarshalIndent(m, "", "  ")
	if err != nil {
		return fmt.Sprintf("[JSON error %v on %#v]", err, m)
	}
	return string(bs)
}

func jstr(m map[string]interface{}, key string) string {
	if s, ok := m[key].(string); ok {
		return s
	}
	return ""
}

func sortedKeys(m map[string]interface{}) (keys []string) {
	for key := range m {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	return
}

func jobj(m map[string]interface{}, key string) map[string]interface{} {
	if m, ok := m[key].(map[string]interface{}); ok {
		return m
	}
	return nil
}

func jobjlist(m map[string]interface{}, key string) []map[string]interface{} {
	si, ok := m[key].([]interface{})
	if !ok {
		return nil
	}
	var sl []map[string]interface{}
	for _, si := range si {
		sl = append(sl, si.(map[string]interface{}))
	}
	return sl
}

func jstrlist(m map[string]interface{}, key string) []string {
	si, ok := m[key].([]interface{})
	if !ok {
		return nil
	}
	sl := make([]string, 0)
	for _, si := range si {
		sl = append(sl, si.(string))
	}
	return sl
}
