// The cdpgen command generates the package cdp from the provided protocol definitions.
package main

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"go/format"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path"
	"sort"
	"strings"

	"github.com/mafredri/cdp/cmd/cdpgen/proto"
)

// Global constants.
const (
	OptionalPropPrefix = ""
	realEnum           = false
)

var (
	nonPtrMap = make(map[string]bool)
)

func panicErr(err error) {
	if err != nil {
		panic(err)
	}
}

func mkdir(name string) error {
	err := os.Mkdir(name, 0755)
	if os.IsExist(err) {
		return nil
	}
	return err
}

func main() {
	var (
		destPkg          string
		browserProtoJSON string
		jsProtoFileJSON  string
	)
	flag.StringVar(&destPkg, "dest-pkg", "", "Destination for generated cdp package (inside $GOPATH)")
	flag.StringVar(&browserProtoJSON, "browser-proto", "./protodef/browser_protocol.json", "Path to browser protocol")
	flag.StringVar(&jsProtoFileJSON, "js-proto", "./protodef/js_protocol.json", "Path to JS protocol")
	flag.Parse()

	if destPkg == "" {
		fmt.Fprintln(os.Stderr, "error: dest-pkg must be set")
		os.Exit(1)
	}

	var protocol, jsProtocol proto.Protocol
	protocolData, err := ioutil.ReadFile(browserProtoJSON)
	panicErr(err)

	err = json.Unmarshal(protocolData, &protocol)
	panicErr(err)

	jsProtocolData, err := ioutil.ReadFile(jsProtoFileJSON)
	panicErr(err)

	err = json.Unmarshal(jsProtocolData, &jsProtocol)
	panicErr(err)

	protocol.Domains = append(protocol.Domains, jsProtocol.Domains...)
	sort.Slice(protocol.Domains, func(i, j int) bool {
		return protocol.Domains[i].Domain < protocol.Domains[j].Domain
	})

	protoDest := path.Join(destPkg, "protocol")
	imports := []string{
		"github.com/mafredri/cdp/rpcc",
		"github.com/mafredri/cdp/protocol/internal",
		"github.com/mafredri/cdp/protocol",
	}
	for i, d := range protocol.Domains {
		dLower := strings.ToLower(d.Name())
		imports = append(imports, path.Join(protoDest, dLower))

		for ii, t := range d.Types {
			nam := t.Name(d)
			if isNonPointer(d.Domain, d, t) {
				nonPtrMap[nam] = true
				nonPtrMap[d.Domain+"."+nam] = true
			}

			// Reference the FrameId in the Frame type.
			if d.Domain == "Page" && t.IDName == "Frame" {
				for iii, p := range t.Properties {
					if p.NameName == "id" || p.NameName == "parentId" {
						p.Ref = "FrameId"
						t.Properties[iii] = p
					}
				}
			}
			d.Types[ii] = t
		}
		protocol.Domains[i] = d
	}
	nonPtrMap["Timestamp"] = true
	nonPtrMap["protocol.Timestamp"] = true
	nonPtrMap["TimeSinceEpoch"] = true
	nonPtrMap["network.TimeSinceEpoch"] = true
	nonPtrMap["MonotonicTime"] = true
	nonPtrMap["network.MonotonicTime"] = true

	var cdp, g Generator
	cdp.imports = imports
	g.imports = imports

	// Define the cdp Client.
	cdp.pkg = "cdp"
	cdp.dir = destPkg
	cdp.PackageHeader("")
	cdp.CdpClient(protocol.Domains)
	cdp.writeFile("cdp_client.go")

	// Package cdp/protocol.
	g.pkg = "protocol"
	g.dir = protoDest
	err = mkdir(g.path())
	panicErr(err)

	// Package cdp/protocol/internal.
	g.pkg = "internal"
	g.dir = path.Join(protoDest, "internal")
	for _, d := range protocol.Domains {
		if d.Name() == "Page" {
			d.Domain = "internal"
			g.PackageHeader("")
			for _, t := range d.Types {
				if t.Name(d) == "FrameID" {
					idName := t.Name(d)
					t.IDName = "Page" + t.IDName
					t.Description = fmt.Sprintf("%s\n\nThis type cannot be used directly. Use page.%s instead.", t.Description, idName)
					g.DomainType(d, t)
				}
			}
			g.writeFile("page.go")
		}
	}

	// Generate the protocol definitions.
	for _, d := range protocol.Domains {
		cdp.PackageHeader("")
		cdp.DomainInterface(d)

		dLower := strings.ToLower(d.Domain)
		g.dir = path.Join(protoDest, dLower)
		g.pkg = dLower
		err := mkdir(g.path())
		panicErr(err)

		comment := fmt.Sprintf("Package %s implements the %s domain. ", dLower, d.Name())
		g.PackageHeader(fmt.Sprintf("// %s%s", comment, d.Desc(0, len(comment))))
		g.DomainDefinition(d)
		g.writeFile("domain.go")

		if len(d.Types) > 0 {
			g.PackageHeader("")
			for _, t := range d.Types {
				g.DomainType(d, t)
			}
			g.writeFile("types.go")
		}

		if len(d.Commands) > 0 {
			g.PackageHeader("")
			for _, c := range d.Commands {
				if c.Redirect != "" {
					continue
				}
				g.DomainCmd(d, c)
			}
			g.writeFile("command.go")
		}

		if len(d.Events) > 0 {
			g.PackageHeader("")
			for _, e := range d.Events {
				g.DomainEvent(d, e)
			}
			g.writeFile("event.go")
		}
	}

	cdp.writeFile(cdp.pkg + ".go")

	g.dir = destPkg

	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	goimports := exec.CommandContext(ctx, "goimports", "-w", g.path())
	out, err := goimports.CombinedOutput()
	if err != nil {
		log.Printf("goimports failed: %s", out)
		log.Println(err)
		os.Exit(1)
	}

	goinstall := exec.CommandContext(ctx, "go", "install", path.Join(destPkg, "..."))
	out, err = goinstall.CombinedOutput()
	if err != nil {
		log.Printf("install failed: %s", out)
		log.Println(err)
		os.Exit(1)
	}
}

// Generator holds the state of the analysis. Primarily used to buffer
// the output for format.Source.
type Generator struct {
	dir        string
	pkg        string
	imports    []string
	buf        bytes.Buffer // Accumulated output.
	testbuf    bytes.Buffer // Accumulated test output.
	hasContent bool
	hasHeader  bool
}

func (g *Generator) path() string {
	return path.Join(os.Getenv("GOPATH"), "src", g.dir)
}

// Printf prints to the Generator buffer.
func (g *Generator) Printf(format string, args ...interface{}) {
	fmt.Fprintf(&g.buf, format, args...)
}

// TestPrintf prints to the Generator test buffer.
func (g *Generator) TestPrintf(format string, args ...interface{}) {
	// No-op
	// fmt.Fprintf(&g.testbuf, format, args...)
}

func (g *Generator) writeFile(f string) {
	fp := path.Join(g.path(), f)
	if !g.hasContent {
		log.Printf("No content, skipping %s...", fp)
		g.clear()
		return
	}
	if g.buf.Len() == 0 {
		log.Printf("Empty buffer, skipping %s...", fp)
		return
	}
	log.Printf("Writing %s...", fp)
	err := ioutil.WriteFile(fp, g.format(), 0644)
	panicErr(err)

	if g.testbuf.Len() > 0 {
		g.buf.Reset()
		g.Printf("package %s\n\n", g.pkg)
		_, err = g.testbuf.WriteTo(&g.buf)
		panicErr(err)
		fptest := strings.Replace(fp, ".go", "_test.go", 1)
		log.Printf("Writing %s...", fptest)

		err = ioutil.WriteFile(fptest, g.format(), 0644)
		panicErr(err)
	}
	g.clear()
}

func (g *Generator) clear() {
	g.hasContent = false
	g.hasHeader = false
	g.buf.Reset()
	g.testbuf.Reset()
}

// format returns the gofmt-ed contents of the Generator's buffer.
func (g *Generator) format() []byte {
	src, err := format.Source(g.buf.Bytes())
	if err != nil {
		// Should never happen, but can arise when developing this code.
		// The user can compile the output to see the error.
		log.Printf("warning: internal error: invalid Go generated: %s", err)
		log.Printf("warning: compile the package to analyze the error")
		return g.buf.Bytes()
	}
	return src
}

// CdpClient creates the cdp.Client type.
func (g *Generator) CdpClient(domains []proto.Domain) {
	g.hasContent = true
	var fields, newFields Generator
	for _, d := range domains {
		fields.Printf("\t%s %s\n", d.Name(), d.Type())
		newFields.Printf("\t\t%s: %s.NewClient(conn),\n", d.Name(), strings.ToLower(d.Name()))
	}
	g.Printf(`
// Client represents a Chrome DevTools Protocol client that can be used to
// invoke methods or listen to events in every CDP domain. The Client consumes
// a rpcc connection, used to invoke the methods.
type Client struct {
	%s
}

// NewClient returns a new Client that uses conn
// for communication with the debugging target.
func NewClient(conn *rpcc.Conn) *Client {
	return &Client{
		%s
	}
}
`, fields.buf.Bytes(), newFields.buf.Bytes())
}

// PackageHeader writes the header for a package.
func (g *Generator) PackageHeader(comment string) {
	if g.hasHeader {
		return
	}
	g.hasHeader = true
	g.Printf(`// Code generated by cdpgen. DO NOT EDIT.

%s
package %s

import (
	"context"
	"encoding/json"
	"fmt"

	%s
)
`, comment, g.pkg, quotedImports(g.imports))
}

// DomainInterface defines the domain interface.
func (g *Generator) DomainInterface(d proto.Domain) {
	g.hasContent = true

	comment := "The " + d.Name() + " domain. "
	desc := d.Desc(0, len(comment))
	if d.Deprecated {
		desc = "\n//\n// Deprecated: " + desc
	}
	if d.Experimental {
		desc += "\n//\n// Note: This domain is experimental."
	}
	g.Printf(`
// %[1]s%[2]s
type %[3]s interface{`, comment, desc, d.Name())
	for _, c := range d.Commands {
		if c.Redirect != "" {
			continue
		}
		request := ""
		reply := "error"
		if len(c.Parameters) > 0 {
			request = ", *" + strings.ToLower(d.Name()) + "." + c.ArgsName(d)
		}
		if len(c.Returns) > 0 {
			reply = fmt.Sprintf("(*%s.%s, error)", strings.ToLower(d.Name()), c.ReplyName(d))
		}
		desc := c.Desc(true, 8, 0)
		if c.Deprecated {
			desc = strings.Replace(c.Desc(true, 8, 12), "Deprecated, ", "", 1)
			desc = "Deprecated: " + strings.ToUpper(desc[0:1]) + desc[1:]
		}
		if desc != "" {
			desc = "\n\t//\n\t// " + desc
		}
		if c.Experimental {
			desc += "\n\t//\n\t// Note: This command is experimental."
		}
		g.Printf("\n\t// Command %s%s\n\t%s(context.Context%s) %s\n", c.Name(), desc, c.Name(), request, reply)
	}
	for _, e := range d.Events {
		eventClient := fmt.Sprintf("%sClient", e.EventName(d))
		desc := e.Desc(true, 8, 0)
		if e.Deprecated {
			desc = strings.Replace(e.Desc(true, 8, 12), "Deprecated, ", "", 1)
			desc = "Deprecated: " + strings.ToUpper(desc[0:1]) + desc[1:]
		}
		if desc != "" {
			desc = "\n\t//\n\t// " + desc
		}
		if e.Experimental {
			desc += "\n//\n// Note: This event is experimental."
		}
		g.Printf("\n\t// Event %s%s\n\t%s(context.Context) (%s.%s, error)\n", e.Name(), desc, e.Name(), strings.ToLower(d.Name()), eventClient)
	}
	g.Printf("}\n")
}

// DomainDefinition defines the entire domain.
func (g *Generator) DomainDefinition(d proto.Domain) {
	g.hasContent = true

	comment := fmt.Sprintf("domainClient is a client for the %s domain. ", d.Name())
	g.Printf(`
// %[1]s%[3]s
type domainClient struct{ conn *rpcc.Conn }

// NewClient returns a client for the %[2]s domain with the connection set to conn.
func NewClient(conn *rpcc.Conn) *domainClient {
	return &domainClient{conn: conn}
}
`, comment, d.Name(), d.Desc(0, len(comment)))

	for _, c := range d.Commands {
		if c.Redirect != "" {
			continue
		}
		request := ""
		invokeReply := "nil"
		if len(c.Parameters) > 0 {
			request = ", args *" + c.ArgsName(d)
		}
		reply := "(err error)"
		if len(c.Returns) > 0 {
			reply = fmt.Sprintf("(reply *%s, err error)", c.ReplyName(d))
		}
		comment := fmt.Sprintf("%[1]s invokes the %[2]s method. ", c.Name(), d.Name())
		g.Printf(`
// %[2]s%[5]s
func (d *domainClient) %[1]s(ctx context.Context%[3]s) %[4]s {`, c.Name(), comment, request, reply, c.Desc(true, 0, len(comment)))
		if len(c.Returns) > 0 {
			g.Printf(`
	reply = new(%s)`, c.ReplyName(d))
			invokeReply = "reply"
		}
		if len(c.Parameters) > 0 {
			g.Printf(`
	if args != nil {
		err = rpcc.Invoke(ctx, %[1]q, args, %[2]s, d.conn)
	} else {
		err = rpcc.Invoke(ctx, %[1]q, nil, %[2]s, d.conn)
	}
	if err != nil {
		err = &internal.OpError{Domain: %[3]q, Op: %[4]q, Err: err}
	}
	return
}
`, d.Domain+"."+c.NameName, invokeReply, d.Name(), c.Name())
		} else {
			g.Printf(`
	err = rpcc.Invoke(ctx, %q, nil, %s, d.conn)
	if err != nil {
		err = &internal.OpError{Domain: %q, Op: %q, Err: err}
	}
	return
}
`, d.Domain+"."+c.NameName, invokeReply, d.Name(), c.Name())
		}

		// Generate method tests.
		g.TestPrintf(`
func Test%[1]s_%[2]s(t *testing.T) {
	conn, codec, cleanup := newTestConn(t)
	defer cleanup()

	dom := New%[1]s(conn)
	var err error
`, d.Name(), c.Name())
		assign := "err"
		if len(c.Returns) > 0 {
			assign = "_, err"
		}
		if len(c.Parameters) > 0 {
			g.TestPrintf(`
	// Test nil args.
	%[1]s = dom.%[2]s(nil, nil)
	if err != nil {
		t.Error(err)
	}
	// Test args.
	%[1]s = dom.%[2]s(nil, &%[3]s{})`, assign, c.Name(), c.ArgsName(d))
		} else {
			g.TestPrintf(`
	%[1]s = dom.%[2]s(nil)`, assign, c.Name())
		}
		g.TestPrintf(`
	if err != nil {
		t.Error(err)
	}

	// Test error.
	codec.respErr = errors.New("bad request")`)
		if len(c.Parameters) > 0 {
			g.TestPrintf(`
	%[1]s = dom.%[2]s(nil, &%[3]s{})`, assign, c.Name(), c.ArgsName(d))
		} else {
			g.TestPrintf(`
	%[1]s = dom.%[2]s(nil)`, assign, c.Name())
		}
		g.TestPrintf(`
	if err == nil || err.(*internal.OpError).Err.(*rpcc.ResponseError).Message != codec.respErr.Error() {
		t.Errorf("unexpected error; got: %%v, want bad request", err)
	}`)
		g.TestPrintf(`
}
`)

	}
	for _, e := range d.Events {
		eventClient := fmt.Sprintf("%sClient", e.EventName(d))
		eventClientImpl := strings.ToLower(string(eventClient[0])) + eventClient[1:]

		// Implement event on domain.
		g.Printf(`
func (d *domainClient) %s(ctx context.Context) (%s, error) {
	s, err := rpcc.NewStream(ctx, %q, d.conn)
	if err != nil {
		return nil, err
	}
	return &%s{Stream: s}, nil
}
`, e.Name(), eventClient, d.Domain+"."+e.NameName, eventClientImpl)

		g.Printf(`
type %[4]s struct { rpcc.Stream }

// GetStream returns the original Stream for use with cdp.Sync.
func (c *%[4]s) GetStream() rpcc.Stream { return c.Stream }

func (c *%[4]s) Recv() (*%[3]s, error) {
	event := new(%[3]s)
	if err := c.RecvMsg(event); err != nil {
		return nil, &internal.OpError{Domain: %[5]q, Op: "%[6]s Recv", Err: err}
	}
	return event, nil
}
`, eventClient, "", e.ReplyName(d), eventClientImpl, d.Name(), e.Name())

		// Generate event tests.
		g.TestPrintf(`
func Test%[1]s_%[2]s(t *testing.T) {
	conn, codec, cleanup := newTestConn(t)
	defer cleanup()

	dom := New%[1]s(conn)

	stream, err := dom.%[2]s(nil)
	if err != nil {
		t.Fatal(err)
	}
	defer stream.Close()

	codec.event = %[3]s.String()
	codec.conn <- nil
	_, err = stream.Recv()
	if err != nil {
		t.Error(err)
	}

	codec.eventArgs = []byte("invalid json")
	codec.conn <- nil
	_, err = stream.Recv()
	if err, ok := err.(*internal.OpError); !ok {
		t.Errorf("Recv() got %%v, want internal.OpError", err)
	}

	conn.Close()
	stream, err = dom.%[2]s(nil)
	if err == nil {
		t.Errorf("Open stream: got nil, want error")
	}
`, d.Name(), e.Name(), e.EventName(d))
		g.TestPrintf(`
}
`)
	}
}

// DomainType creates the type definition.
func (g *Generator) DomainType(d proto.Domain, t proto.AnyType) {
	g.hasContent = true

	var comment string
	if d.Name() == "Page" && (t.Name(d) == "FrameID") {
		comment = "//"
		g.Printf(`
// %[1]s %[2]s
//
// Provided as an alias to prevent circular dependencies.
type %[1]s = internal.Page%[1]s
`, t.Name(d), t.Desc(0, len(t.Name(d))+1))
	}
	desc := t.Desc(0, len(t.Name(d))+1)
	if t.Deprecated {
		desc = "\n//\n// Deprecated: " + t.Desc(0, 12)
	}
	if t.Experimental {
		desc = desc + "\n//\n// Note: This type is experimental."
	}
	g.Printf(`
// %[1]s %[2]s
%[3]stype %[1]s `, t.Name(d), desc, comment)

	typ := t.GoType(g.pkg, d)
	switch typ {
	case "struct":
		g.domainTypeStruct(d, t)
	case "enum":
		g.domainTypeEnum(d, t)
	case "time.Time":
		g.domainTypeTime(d, t)
	case "RawMessage":
		g.domainTypeRawMessage(d, t)
	default:
		g.Printf(typ)
	}
	g.Printf("\n\n")
}

func (g *Generator) printStructProperties(d proto.Domain, name string, props []proto.AnyType, ptrOptional, renameOptional bool) {
	for _, prop := range props {
		jsontag := prop.NameName
		ptype := prop.GoType(g.pkg, d)

		if ptype == "page.FrameID" {
			if g.pkg == "network" || g.pkg == "dom" {
				// Domain-local type (alias).
				ptype = strings.Replace(ptype, "page.", "internal.Page", 1)
			}
		}

		// Make all optional properties into pointers, unless they are slices.
		if prop.Optional {
			isNonPtr := nonPtrMap[ptype]
			if ptrOptional && !isNonPtr && !isNonPointer(g.pkg, d, prop) {
				ptype = "*" + ptype
			}
			jsontag += ",omitempty"
		}

		// Avoid recursive type definitions.
		if ptype == name {
			ptype = "*" + ptype
		}

		exportedName := prop.ExportedName(d)
		if renameOptional && prop.Optional {
			exportedName = OptionalPropPrefix + exportedName
		}

		var preDesc, postDesc string

		desc := prop.Desc(8, len(exportedName)+1)
		var deprecated, localEnum, experimental string
		if prop.Deprecated {
			desc = prop.Desc(8, 12)
			if desc == "" {
				desc = "This property should not be used."
			}
			deprecated = "//\n// Deprecated: " + desc + "\n"
			desc = "is deprecated."
		}
		if prop.IsLocalEnum() {
			var enums []string
			for _, e := range prop.Enum {
				enums = append(enums, fmt.Sprintf("%q", e))
			}
			localEnum = "//\n// Values: " + strings.Join(enums, ", ") + ".\n"
		}
		if prop.Experimental {
			experimental = "//\n// Note: This property is experimental.\n"
		}
		if deprecated != "" || localEnum != "" || experimental != "" {
			preDesc = "// " + exportedName + " " + desc + "\n" + deprecated + localEnum + experimental
		} else {
			if desc == "" {
				desc = "No description."
			}
			postDesc = "// " + enforceSingleLine(desc)
		}

		g.Printf("\t%s%s %s `json:\"%s\"` %s\n", preDesc, exportedName, ptype, jsontag, postDesc)
	}
}

func enforceSingleLine(s string) string {
	return strings.Replace(s, "\n//", "", -1)
}

func (g *Generator) domainTypeStruct(d proto.Domain, t proto.AnyType) {
	g.Printf("struct{\n")
	g.printStructProperties(d, t.Name(d), t.Properties, true, false)
	g.Printf("}")
}

func (g *Generator) domainTypeTime(d proto.Domain, t proto.AnyType) {
	var div int
	if d.Name() == "Runtime" {
		// Runtime domain denotes timestamps in milliseconds.
		div = 1000
	} else {
		div = 1
	}

	g.Printf(`float64

// String calls (time.Time).String().
func (t %[1]s) String() string {
	return t.Time().String()
}

// Time parses the Unix time.
func (t %[1]s) Time() time.Time {
	ts := float64(t) / %[3]d
	secs := int64(ts)
	nsecs := int64((ts - float64(secs)) * 1000000000)
	return time.Unix(secs, nsecs)
}

// MarshalJSON implements json.Marshaler. Encodes to null if t is zero.
func (t %[1]s) MarshalJSON() ([]byte, error) {
	if t == 0 {
		return []byte("null"), nil
	}
	f := float64(t)
	return json.Marshal(&f)
}

// UnmarshalJSON implements json.Unmarshaler.
func (t *%[1]s) UnmarshalJSON(data []byte) error {
	*t = 0
	if len(data) == 0 {
		return nil
	}
	var f float64
	if err := json.Unmarshal(data, &f); err != nil {
		return errors.New("%[2]s.%[1]s: " + err.Error())
	}
	*t = %[1]s(f)
	return nil
}

var _ json.Marshaler = (*%[1]s)(nil)
var _ json.Unmarshaler = (*%[1]s)(nil)
`, t.Name(d), g.pkg, div)

	g.TestPrintf(`
func Test%[1]s_Marshal(t *testing.T) {
	var v %[1]s

	// Test empty.
	b, err := json.Marshal(&v)
	if err != nil {
		t.Errorf("Marshal() got %%v, want no error", err)
	}
	if string(b) != "null" {
		t.Errorf("Marshal() got %%s, want null", b)
	}
	err = json.Unmarshal(b, &v)
	if err != nil {
		t.Errorf("Unmarshal() got %%v, want no error", err)
	}

	// Test non-empty.
	v = 1
	b, err = json.Marshal(&v)
	if err != nil {
		t.Errorf("Marshal() got %%v, want no error", err)
	}
	if string(b) != "1" {
		t.Errorf("Marshal() got %%s, want 1", b)
	}
	err = json.Unmarshal(b, &v)
	if err != nil {
		t.Errorf("Unmarshal() got %%v, want no error", err)
	}
}
`, t.Name(d))
}

func (g *Generator) domainTypeRawMessage(d proto.Domain, t proto.AnyType) {
	g.Printf(`[]byte

// MarshalJSON copies behavior of json.RawMessage.
func (%[3]s %[1]s) MarshalJSON() ([]byte, error) {
	if %[3]s == nil {
		return []byte("null"), nil
	}
	return %[3]s, nil
}

// UnmarshalJSON copies behavior of json.RawMessage.
func (%[3]s *%[1]s) UnmarshalJSON(data []byte) error {
	if %[3]s == nil {
		return errors.New("%[2]s.%[1]s: UnmarshalJSON on nil pointer")
	}
	*%[3]s = append((*%[3]s)[0:0], data...)
	return nil
}

var _ json.Marshaler = (*%[1]s)(nil)
var _ json.Unmarshaler = (*%[1]s)(nil)
`, t.Name(d), g.pkg, t.Recvr(d))

	g.TestPrintf(`
func Test%[1]s_Marshal(t *testing.T) {
	var v %[1]s

	// Test empty.
	b, err := json.Marshal(&v)
	if err != nil {
		t.Errorf("Marshal() got %%v, want no error", err)
	}
	if string(b) != "null" {
		t.Errorf("Marshal() got %%s, want null", b)
	}
	err = json.Unmarshal(b, &v)
	if err != nil {
		t.Errorf("Unmarshal() got %%v, want no error", err)
	}

	// Test non-empty.
	v = []byte("\"test\"")
	b, err = json.Marshal(&v)
	if err != nil {
		t.Errorf("Marshal() got %%v, want no error", err)
	}
	if !bytes.Equal(v, b) {
		t.Errorf("Marshal() got %%s, want %%s", b, v)
	}
	v = nil
	err = json.Unmarshal(b, &v)
	if err != nil {
		t.Errorf("Unmarshal() got %%v, want no error", err)
	}
	if !bytes.Equal(v, b) {
		t.Errorf("Unmarshal() got %%s, want %%s", b, v)
	}
}
`, t.Name(d))
}

func (g *Generator) domainTypeEnum(d proto.Domain, t proto.AnyType) {
	if t.Type != "string" {
		log.Panicf("unknown enum type: %s", t.Type)
	}

	// Verify assumption about enums never being the empty string, this
	// allows us to consider optional enums as type string instead of
	// *string when encoding to JSON (omitempty).
	for _, e := range t.Enum {
		if e == "" {
			panic("enum " + t.Name(d) + " has unexpected empty enum value")
		}
	}

	name := strings.Title(t.Name(d))
	if realEnum {
		g.Printf("int\n\n")

		format := `
// %s as enums.
const (
	%sNotSet %s = iota`
		g.Printf(format, name, name, name)
		for _, e := range t.Enum {
			g.Printf("\n\t%s%s", name, e.Name())
		}
		g.Printf(`
)
`)
		g.Printf(`
// Valid returns true if enum is set.
func (e %[1]s) Valid() bool {
	return e >= 1 && e <= %[2]d
}

func (e %[1]s) String() string {
	switch e {
	case 0:
		return "%[1]sNotSet"`, name, len(t.Enum))
		for i, e := range t.Enum {
			g.Printf(`
	case %d:
		return "%s"`, i+1, e)
		}
		g.Printf(`
	}
	return fmt.Sprintf("%[1]s(%%d)", e)
}

// MarshalJSON encodes enum into a string or null when not set.
func (e %[1]s) MarshalJSON() ([]byte, error) {
	if e == 0 {
		return []byte("null"), nil
	}
	if !e.Valid() {
		return nil, errors.New("%[2]s.%[1]s: MarshalJSON on bad enum value: " + e.String())
	}
	return json.Marshal(e.String())
}

// UnmarshalJSON decodes a string value into a enum.
func (e *%[1]s) UnmarshalJSON(data []byte) error {
	switch string(data) {
	case "null":
		*e = 0`, name, g.pkg)
		for i, e := range t.Enum {
			g.Printf(`
	case "\"%s\"":
		*e = %d`, e, i+1)
		}
		g.Printf(`
	default:
		return fmt.Errorf("%s.%s: UnmarshalJSON on bad input: %%s", data)
	}
	return nil
}`, g.pkg, name)
	} else {
		g.Printf("string\n\n")

		g.Printf(`
// %s as enums.
const (`, name)
		format := "\n\t%s%s %s = %q"
		g.Printf(format, name, "NotSet", name, "")

		for _, e := range t.Enum {
			g.Printf(format, name, e.Name(), name, e)
		}
		g.Printf(`
)
`)

		var enumValues []string
		for _, e := range t.Enum {
			enumValues = append(enumValues, fmt.Sprintf("%q", e))
		}

		g.Printf(`
func (e %[1]s) Valid() bool {
	switch e {
	case %[2]s:
		return true
	default:
		return false
	}
}

func (e %[1]s) String() string {
	return string(e)
}
`, t.Name(d), strings.Join(enumValues, ", "))
	}
}

// CmdType generates the type for CDP methods names.
func (g *Generator) CmdType(doms []proto.Domain) {
	g.hasContent = true
	g.Printf(`
// CmdType is the type for CDP methods names.
type CmdType string

func (c CmdType) String() string {
	return string(c)
}

// Cmd methods.
const (`)
	for _, d := range doms {
		for _, c := range d.Commands {
			g.Printf("\n\t%s CmdType = %q", c.CmdName(d, true), d.Domain+"."+c.NameName)
		}
	}
	g.Printf("\n)\n")
}

// DomainCmd defines the command args and reply.
func (g *Generator) DomainCmd(d proto.Domain, c proto.Command) {
	if len(c.Parameters) > 0 {
		g.hasContent = true
		g.domainCmdArgs(d, c)
	}
	if len(c.Returns) > 0 {
		g.hasContent = true
		g.domainCmdReply(d, c)
	}
}

func (g *Generator) domainCmdArgs(d proto.Domain, c proto.Command) {
	g.Printf(`
// %[1]s represents the arguments for %[2]s in the %[3]s domain.
type %[1]s struct {
`, c.ArgsName(d), c.Name(), d.Name())
	g.printStructProperties(d, c.ArgsName(d), c.Parameters, true, true)
	g.Printf("}\n\n")

	newfmt := `
// New%[1]s initializes %[4]s with the required arguments.
func New%[1]s(%[2]s) *%[1]s {
	args := new(%[1]s)
	%[3]s
	return args
}
`
	sig := c.ArgsSignature(d)
	if d.Name() == "DOM" {
		sig = strings.Replace(sig, "page.FrameID", "internal.PageFrameID", 1)
	}
	g.Printf(newfmt, c.ArgsName(d), sig, c.ArgsAssign("args", d), c.ArgsName(d))

	// Test the new arguments.
	testInit := ""
	if c.ArgsSignature(d) != "" {
		testInit = fmt.Sprintf("func() (%s) { return }()", c.ArgsSignature(d))
	}
	g.TestPrintf(`
func TestNew%[1]s(t *testing.T) {
	args := New%[1]s(%[2]s)
	if args == nil {
		t.Errorf("New%[1]s returned nil args")
	}
}
`, c.ArgsName(d), testInit)

	for _, arg := range c.Parameters {
		if !arg.Optional {
			continue
		}
		typ := arg.GoType(g.pkg, d)
		isNonPtr := nonPtrMap[typ]
		ptr := "&"
		if isNonPtr || isNonPointer(g.pkg, d, arg) {
			ptr = ""
		}
		name := arg.Name(d)
		if name == "range" || name == "type" {
			name = name[0 : len(name)-1]
		}
		comment := fmt.Sprintf("Set%[1]s sets the %[1]s optional argument. ", arg.ExportedName(d))
		desc := arg.Desc(8, len(comment))
		if arg.Deprecated {
			if desc == "" {
				desc = "This property should not be used."
			}
			desc = "\n//\n// Deprecated: " + desc
		}
		if arg.IsLocalEnum() {
			var enums []string
			for _, e := range arg.Enum {
				enums = append(enums, fmt.Sprintf("%q", e))
			}
			desc += "\n//\n// Values: " + strings.Join(enums, ", ") + "."
		}
		if arg.Experimental {
			desc += "\n//\n// Note: This property is experimental."
		}
		setMethodFmt := fmt.Sprintf(`
// %[7]s%[5]s
func (a *%[2]s) Set%[1]s(%[3]s %%[1]s) *%[2]s {
	a.%[4]s%[1]s = %[6]s%[3]s
	return a
}
`, arg.ExportedName(d), c.ArgsName(d), name, OptionalPropPrefix, desc, ptr, comment)

		argType := arg.GoType("cdp", d)
		g.Printf(setMethodFmt, argType)
	}
}

func (g *Generator) domainCmdReply(d proto.Domain, c proto.Command) {
	g.Printf(`
// %[1]s represents the return values for %[2]s in the %[3]s domain.
type %[1]s struct {
`, c.ReplyName(d), c.Name(), d.Name())
	g.printStructProperties(d, c.ReplyName(d), c.Returns, true, false)
	g.Printf("}\n\n")
}

// EventType generates the type for CDP event names.
func (g *Generator) EventType(doms []proto.Domain) {
	g.hasContent = true
	g.Printf(`
// EventType is the type for CDP event names.
type EventType string

func (e EventType) String() string {
	return string(e)
}

// Event methods.
const (`)
	for _, d := range doms {
		for _, e := range d.Events {
			g.Printf("\n\t%s EventType = %q", e.EventName(d), d.Domain+"."+e.NameName)
		}
	}
	g.Printf("\n)\n")
}

// DomainEvent defines the event client and reply.
func (g *Generator) DomainEvent(d proto.Domain, e proto.Event) {
	g.hasContent = true
	g.domainEventClient(d, e)

	g.domainEventReply(d, e)
}

func (g *Generator) domainEventClient(d proto.Domain, e proto.Event) {
	eventClient := fmt.Sprintf("%sClient", e.EventName(d))
	comment := fmt.Sprintf("%[1]s is a client for %[2]s events. ", eventClient, e.Name())
	g.Printf(`
// %[2]s%[4]s
type %[1]s interface {
	// Recv calls RecvMsg on rpcc.Stream, blocks until the event is
	// triggered, context canceled or connection closed.
	Recv() (*%[3]s, error)
	rpcc.Stream
}
`, eventClient, comment, e.ReplyName(d), e.Desc(true, 0, len(comment)))
}

func (g *Generator) domainEventReply(d proto.Domain, e proto.Event) {
	g.Printf(`
// %[1]s is the reply for %[2]s events.
type %[1]s struct {
`, e.ReplyName(d), e.Name())
	g.printStructProperties(d, e.ReplyName(d), e.Parameters, true, false)
	g.Printf("}\n")
}

func quotedImports(imports []string) string {
	if len(imports) == 0 {
		return ""
	}

	return "\"" + strings.Join(imports, "\"\n\"") + "\""
}

func isNonPointer(pkg string, d proto.Domain, t proto.AnyType) bool {
	typ := t.GoType(pkg, d)
	switch {
	case t.IsEnum():
	case strings.HasPrefix(typ, "[]"):
	case strings.HasPrefix(typ, "map["):
	case typ == "time.Time":
	case typ == "json.RawMessage":
	case typ == "RawMessage":
	case typ == "interface{}":
	default:
		return false
	}
	return true
}
