// Copyright 2025 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package codegen

import (
	"fmt"
	"log"
	"sort"
	"strings"

	"go.fuchsia.dev/fuchsia/tools/fidl/lib/fidlgen"
)

type PythonType struct {
	fidlgen.Type
	PythonName string
}

type PythonConst struct {
	fidlgen.Const
	PythonName  string
	PythonValue string
	PythonType  PythonType
}

type PythonBits struct {
	fidlgen.Bits
	PythonName    string
	PythonMembers []PythonBitsMember
	Empty         bool
}

type PythonBitsMember struct {
	fidlgen.BitsMember
	PythonName  string
	PythonValue string
}

type PythonEnum struct {
	fidlgen.Enum
	PythonName    string
	PythonMembers []PythonEnumMember
	Empty         bool
	HasZero       bool
}

type PythonEnumMember struct {
	fidlgen.EnumMember
	PythonName  string
	PythonValue string
}

type PythonTable struct {
	fidlgen.Table
	Library       string
	PythonName    string
	PythonMembers []PythonTableMember
}

type PythonTableMember struct {
	fidlgen.TableMember
	PythonType PythonType
	PythonName string
}

type PythonStruct struct {
	fidlgen.Struct
	Library       string
	PythonName    string
	PythonMembers []PythonStructMember
}

type PythonStructMember struct {
	fidlgen.StructMember
	PythonType PythonType
	PythonName string
}

type PythonUnion struct {
	fidlgen.Union
	Library           string
	PythonName        string
	PythonMembers     []PythonUnionMember
	PythonSuccessType *PythonType
}

type PythonUnionMember struct {
	fidlgen.UnionMember
	PythonType PythonType
	PythonName string
}

type PythonAlias struct {
	fidlgen.Alias
	PythonAliasedName string
	PythonName        string
}

type UnsupportedMessage string

type PythonUnsupported struct {
	Identifier fidlgen.EncodedCompoundIdentifier
	PythonName string
	Message    []string
}

type PythonProtocol struct {
	fidlgen.Protocol
	Discoverable           bool
	Marker                 string
	Library                string
	PythonName             string
	PythonMarkerName       string
	PythonClientName       string
	PythonServerName       string
	PythonEventHandlerName string
	PythonMethods          []PythonMethod
}

type PythonMethod struct {
	fidlgen.Method
	HasFrameworkError            bool
	PythonName                   string
	PythonResponseAlias          string
	PythonRequestPayload         *PythonPayload
	PythonRequestIdent           fidlgen.EncodedCompoundIdentifier
	PythonResponsePayload        *PythonPayload
	PythonResponseSuccessPayload *PythonPayload
	PythonResponseIdentifier     fidlgen.EncodedCompoundIdentifier
	EmptyResponse                bool
}

type PythonPayload struct {
	fidlgen.Type
	DeclType         fidlgen.DeclType
	PythonType       PythonType
	PythonParameters []PythonParameter
}

type PythonParameter struct {
	PythonType        PythonType
	PythonName        string
	PythonNoneDefault bool
}

type PythonRoot struct {
	fidlgen.Root
	PythonModuleName       string
	EmptySuccessStructs    map[fidlgen.EncodedCompoundIdentifier]fidlgen.Struct
	PythonTables           map[fidlgen.EncodedCompoundIdentifier]PythonTable
	PythonStructs          map[fidlgen.EncodedCompoundIdentifier]PythonStruct
	ExternalPythonStructs  map[fidlgen.EncodedCompoundIdentifier]PythonStruct
	PythonUnions           map[fidlgen.EncodedCompoundIdentifier]PythonUnion
	PythonAliases          []PythonAlias
	PythonConsts           []PythonConst
	PythonBits             []PythonBits
	PythonEnums            []PythonEnum
	PythonProtocols        []PythonProtocol
	PythonExternalModules  []string
	PythonUnsupportedTypes []PythonUnsupported
}

type compiler struct {
	decls           fidlgen.DeclInfoMap
	library         fidlgen.EncodedLibraryIdentifier
	externalModules map[string]struct{}
	PythonRoot      PythonRoot
}

func (c *compiler) lookupDeclInfo(val fidlgen.EncodedCompoundIdentifier) *fidlgen.DeclInfo {
	if info, ok := c.decls[val]; ok {
		return &info
	}
	log.Fatalf("Identifier missing from DeclInfoMap: %v", val)
	return nil
}

func compileCamelIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ToUpperCamelCase(string(val))
}

func (c *compiler) inExternalLibrary(eci fidlgen.EncodedCompoundIdentifier) bool {
	return eci.LibraryName() != c.library
}

func ToPythonModuleName(eli fidlgen.EncodedLibraryIdentifier) string {
	return fmt.Sprintf("fidl_%s", strings.Join(eli.Parts(), "_"))
}

func (c *compiler) compileDeclIdentifier(val fidlgen.EncodedCompoundIdentifier) *string {
	ci := val.Parse()

	if ci.Member != "" {
		log.Fatalf("Non-empty Member implies this is not a declaration: %v", val)
	}

	var name string
	if c.lookupDeclInfo(val).Type == fidlgen.ConstDeclType {
		name = compileScreamingSnakeIdentifier(ci.Name)
	} else {
		name = compileCamelIdentifier(ci.Name)
	}

	if val.LibraryName() == c.library {
		return &name
	}

	externalModule := ToPythonModuleName(val.LibraryName())
	c.externalModules[externalModule] = struct{}{}
	externalName := fmt.Sprintf("%s.%s", externalModule, name)
	return &externalName
}

func compileSnakeIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ToSnakeCase(string(val))
}

func compileScreamingSnakeIdentifier(val fidlgen.Identifier) string {
	return fidlgen.ConstNameToAllCapsSnake(string(val))
}

func (c *compiler) compileType(val fidlgen.Type, maybeAlias *fidlgen.PartialTypeConstructor) *PythonType {
	if _, ok := c.PythonRoot.EmptySuccessStructs[val.Identifier]; ok {
		return &PythonType{
			Type:       val,
			PythonName: "None",
		}
	}

	name := ""

	if val.Nullable {
		name = "typing.Optional["
	}

	switch val.Kind {
	case fidlgen.IdentifierType:
		// TODO(https://fxbug.dev/394421154): This should be changed to use the enum type itself
		// when we start making breaking changes for these bindings.
		identifier := *c.compileDeclIdentifier(val.Identifier)
		switch c.decls[val.Identifier].Type {
		case fidlgen.BitsDeclType, fidlgen.EnumDeclType:
			name += fmt.Sprintf("int | %s", identifier)
		default:
			name += identifier
		}
	case fidlgen.PrimitiveType:
		subtype := string(val.PrimitiveSubtype)
		if strings.HasPrefix(subtype, "int") || strings.HasPrefix(subtype, "uint") {
			name += "int"
		} else if strings.HasPrefix(subtype, "float") {
			name += "float"
		} else if subtype == "bool" {
			name += "bool"
		} else {
			log.Fatalf("Unknown primitive subtype: %v", val)
		}
	case fidlgen.StringType:
		name += "str"
	case fidlgen.HandleType:
		name += "int"
	case fidlgen.VectorType, fidlgen.ArrayType:
		element_type_ptr := c.compileType(*val.ElementType, val.MaybeFromAlias)
		if element_type_ptr == nil {
			log.Fatalf("Element type not supported")
		}
		element_type := *element_type_ptr
		name += fmt.Sprintf("typing.Sequence[%s]", element_type.PythonName)
	case fidlgen.EndpointType:
		switch val.Role {
		case fidlgen.ClientRole, fidlgen.ServerRole:
			name += "int"
		default:
			log.Fatalf("Unsupported endpoint role: %v", val)
		}
	case fidlgen.InternalType:
		// TODO(https://fxbug.dev/42061151): Remove "transport_error".
		switch val.InternalSubtype {
		case "framework_error", "transport_error":
			name += "fidl.FrameworkError"
		default:
			log.Fatalf("Unrecognized internal type: %v", val)
		}
	default:
		log.Fatalf("Unknown kind: %v", val)
	}
	if val.Nullable {
		name += "]"
	}
	return &PythonType{
		Type:       val,
		PythonName: name,
	}
}

func (c *compiler) compileAlias(val fidlgen.Alias) PythonAlias {
	t := c.compileType(val.Type, val.MaybeFromAlias)
	if t == nil {
		log.Fatalf("Type not supported")
	}

	return PythonAlias{
		Alias:             val,
		PythonAliasedName: t.PythonName,
		PythonName:        *c.compileDeclIdentifier(val.Name),
	}
}

// TODO(https://fxbug.dev/396552135): Add literal tests to conformance test suite.
func (c *compiler) compileLiteral(val fidlgen.Literal) *string {
	var r string
	switch val.Kind {
	case fidlgen.NumericLiteral:
		r = val.Value
	case fidlgen.BoolLiteral:
		if val.Value == "true" {
			r = "True"
			return &r
		} else if val.Value == "false" {
			r = "False"
		} else {
			log.Fatalf("Unknown bool value: %v", val)
		}
	case fidlgen.StringLiteral:
		r = strings.ReplaceAll(val.Value, "\\", "\\\\")
		r = strings.ReplaceAll(r, "\"", "\\\"")
		r = strings.ReplaceAll(r, "'", "\\'")
		r = strings.ReplaceAll(r, "\x00", "\\x00")
		r = fmt.Sprintf("\"\"\"%s\"\"\"", r)
	default:
		log.Fatalf("Unknown literal kind: %v", val)
	}
	return &r
}

func (c *compiler) compileMemberIdentifier(val fidlgen.EncodedCompoundIdentifier) *string {
	ci := val.Parse()
	if ci.Member == "" {
		log.Fatalf("expected a member: %s", val)
	}
	decl := val.DeclName()
	declType := c.lookupDeclInfo(decl).Type
	var member string
	switch declType {
	case fidlgen.BitsDeclType, fidlgen.EnumDeclType:
		member = compileScreamingSnakeIdentifier(ci.Member)
	default:
		log.Fatalf("unexpected decl type: %s", declType)
	}
	member_identifier := fmt.Sprintf("%s.%s", *c.compileDeclIdentifier(decl), member)
	return &member_identifier
}

func (c *compiler) compileConstant(val fidlgen.Constant, typ fidlgen.Type) *string {
	switch val.Kind {
	case fidlgen.LiteralConstant:
		return c.compileLiteral(*val.Literal)
	case fidlgen.BinaryOperator, fidlgen.IdentifierConstant:
		return &val.Value
	}
	log.Fatalf("Failed to compile constant: %v, %v", val, typ)
	return nil
}

func (c *compiler) compileConst(val fidlgen.Const) PythonConst {
	return PythonConst{
		Const:       val,
		PythonName:  *c.compileDeclIdentifier(val.Name),
		PythonValue: *c.compileConstant(val.Value, val.Type),
		PythonType:  *c.compileType(val.Type, nil),
	}
}

func (c *compiler) compileBits(val fidlgen.Bits) PythonBits {
	e := PythonBits{
		Bits:          val,
		PythonName:    *c.compileDeclIdentifier(val.Name),
		PythonMembers: []PythonBitsMember{},
		Empty:         len(val.Members) == 0,
	}
	for _, member_val := range val.Members {
		e.PythonMembers = append(e.PythonMembers, PythonBitsMember{
			BitsMember:  member_val,
			PythonName:  changeIfReserved(compileScreamingSnakeIdentifier(member_val.Name)),
			PythonValue: *c.compileConstant(member_val.Value, val.Type),
		})
	}
	return e
}

func (c *compiler) compileEnum(val fidlgen.Enum) PythonEnum {
	e := PythonEnum{
		Enum:          val,
		PythonName:    *c.compileDeclIdentifier(val.Name),
		PythonMembers: []PythonEnumMember{},
		Empty:         len(val.Members) == 0,
		HasZero:       false,
	}
	for _, member_val := range val.Members {
		var value string
		switch member_val.Value.Kind {
		case fidlgen.LiteralConstant:
			value = *c.compileLiteral(*member_val.Value.Literal)
			e.HasZero = e.HasZero || (value == "0")
		case fidlgen.BinaryOperator, fidlgen.IdentifierConstant:
			value = member_val.Value.Value
		default:
			log.Fatalf("Unknown enum member kind: %v", member_val)
		}

		e.PythonMembers = append(e.PythonMembers, PythonEnumMember{
			EnumMember:  member_val,
			PythonName:  changeIfReserved(compileScreamingSnakeIdentifier(member_val.Name)),
			PythonValue: value,
		})
	}
	return e
}

func (c *compiler) compileTableMember(val fidlgen.TableMember) PythonTableMember {
	t := c.compileType(val.Type, val.MaybeFromAlias)
	if t == nil {
		log.Fatalf("Type not supported")
	}
	return PythonTableMember{
		TableMember: val,
		PythonType:  *t,
		PythonName:  changeIfReserved(compileSnakeIdentifier(val.Name)),
	}
}

func (c *compiler) compileTable(val fidlgen.Table) PythonTable {
	name := *c.compileDeclIdentifier(val.Name)
	python_table := PythonTable{
		Table:         val,
		Library:       string(val.Name.LibraryName()),
		PythonName:    name,
		PythonMembers: []PythonTableMember{},
	}

	for _, v := range val.Members {
		member := c.compileTableMember(v)
		python_table.PythonMembers = append(python_table.PythonMembers, member)
	}

	return python_table
}

func (c *compiler) compileStructMember(val fidlgen.StructMember) (PythonStructMember, *UnsupportedMessage) {
	if _, ok := val.Attributes.LookupAttribute("allow_deprecated_struct_defaults"); ok {
		message := UnsupportedMessage(fmt.Sprintf("%s annotated with allow_deprecated_struct_defaults", val.Name))
		return PythonStructMember{}, &message
	}
	t := c.compileType(val.Type, val.MaybeFromAlias)
	if t == nil {
		message := UnsupportedMessage(fmt.Sprintf("Failed to compile type of %s", val.Name))
		return PythonStructMember{}, &message
	}
	return PythonStructMember{
		StructMember: val,
		PythonType:   *t,
		PythonName:   changeIfReserved(compileSnakeIdentifier(val.Name)),
	}, nil
}

func (c *compiler) compileStruct(val fidlgen.Struct) (PythonStruct, *PythonUnsupported) {
	name := *c.compileDeclIdentifier(val.Name)
	python_struct := PythonStruct{
		Struct:        val,
		Library:       string(val.Name.LibraryName()),
		PythonName:    name,
		PythonMembers: []PythonStructMember{},
	}

	unsupported_message := ""
	for _, v := range val.Members {
		member, message := c.compileStructMember(v)
		if message != nil {
			if unsupported_message != "" {
				unsupported_message += "\n"
			}
			unsupported_message = fmt.Sprintf("%s- %s", unsupported_message, *message)
			continue
		}
		python_struct.PythonMembers = append(python_struct.PythonMembers, member)
	}
	if unsupported_message != "" {
		unsupported := PythonUnsupported{
			Identifier: val.Name,
			PythonName: name,
			Message:    strings.Split(unsupported_message, "\n"),
		}
		return PythonStruct{}, &unsupported
	}

	return python_struct, nil
}

var pythonReservedWords = map[string]struct{}{
	// LINT.IfChange
	// keep-sorted start
	"ArithmeticError":           {}, //
	"AssertionError":            {}, //
	"AttributeError":            {}, //
	"BaseException":             {}, //
	"BaseExceptionGroup":        {}, //
	"BlockingIOError":           {}, //
	"BrokenPipeError":           {}, //
	"BufferError":               {}, //
	"BytesWarning":              {}, //
	"ChildProcessError":         {}, //
	"ConnectionAbortedError":    {}, //
	"ConnectionError":           {}, //
	"ConnectionRefusedError":    {}, //
	"ConnectionResetError":      {}, //
	"DeprecationWarning":        {}, //
	"EOFError":                  {}, //
	"Ellipsis":                  {}, //
	"EncodingWarning":           {}, //
	"EnvironmentError":          {}, //
	"Exception":                 {}, //
	"ExceptionGroup":            {}, //
	"False":                     {}, //
	"FileExistsError":           {}, //
	"FileNotFoundError":         {}, //
	"FloatingPointError":        {}, //
	"FutureWarning":             {}, //
	"GeneratorExit":             {}, //
	"IOError":                   {}, //
	"ImportError":               {}, //
	"ImportWarning":             {}, //
	"IndentationError":          {}, //
	"IndexError":                {}, //
	"InterruptedError":          {}, //
	"IsADirectoryError":         {}, //
	"KeyError":                  {}, //
	"KeyboardInterrupt":         {}, //
	"LookupError":               {}, //
	"MemoryError":               {}, //
	"ModuleNotFoundError":       {}, //
	"NameError":                 {}, //
	"None":                      {}, //
	"NotADirectoryError":        {}, //
	"NotImplemented":            {}, //
	"NotImplementedError":       {}, //
	"OSError":                   {}, //
	"OverflowError":             {}, //
	"PendingDeprecationWarning": {}, //
	"PermissionError":           {}, //
	"ProcessLookupError":        {}, //
	"RecursionError":            {}, //
	"ReferenceError":            {}, //
	"ResourceWarning":           {}, //
	"RuntimeError":              {}, //
	"RuntimeWarning":            {}, //
	"StopAsyncIteration":        {}, //
	"StopIteration":             {}, //
	"SyntaxError":               {}, //
	"SyntaxWarning":             {}, //
	"SystemError":               {}, //
	"SystemExit":                {}, //
	"TabError":                  {}, //
	"TimeoutError":              {}, //
	"True":                      {}, //
	"TypeError":                 {}, //
	"UnboundLocalError":         {}, //
	"UnicodeDecodeError":        {}, //
	"UnicodeEncodeError":        {}, //
	"UnicodeError":              {}, //
	"UnicodeTranslateError":     {}, //
	"UnicodeWarning":            {}, //
	"UserWarning":               {}, //
	"ValueError":                {}, //
	"Warning":                   {}, //
	"ZeroDivisionError":         {}, //
	"abs":                       {}, //
	"aiter":                     {}, //
	"all":                       {}, //
	"and":                       {}, //
	"anext":                     {}, //
	"any":                       {}, //
	"as":                        {}, //
	"ascii":                     {}, //
	"assert":                    {}, //
	"async":                     {}, //
	"await":                     {}, //
	"bin":                       {}, //
	"bool":                      {}, //
	"break":                     {}, //
	"breakpoint":                {}, //
	"bytearray":                 {}, //
	"bytes":                     {}, //
	"callable":                  {}, //
	"case":                      {}, //
	"chr":                       {}, //
	"class":                     {}, //
	"classmethod":               {}, //
	"compile":                   {}, //
	"complex":                   {}, //
	"continue":                  {}, //
	"copyright":                 {}, //
	"credits":                   {}, //
	"def":                       {}, //
	"del":                       {}, //
	"delattr":                   {}, //
	"dict":                      {}, //
	"dir":                       {}, //
	"divmod":                    {}, //
	"elif":                      {}, //
	"else":                      {}, //
	"enumerate":                 {}, //
	"eval":                      {}, //
	"except":                    {}, //
	"exec":                      {}, //
	"exit":                      {}, //
	"filter":                    {}, //
	"finally":                   {}, //
	"float":                     {}, //
	"for":                       {}, //
	"format":                    {}, //
	"from":                      {}, //
	"frozenset":                 {}, //
	"getattr":                   {}, //
	"global":                    {}, //
	"globals":                   {}, //
	"hasattr":                   {}, //
	"hash":                      {}, //
	"help":                      {}, //
	"hex":                       {}, //
	"id":                        {}, //
	"if":                        {}, //
	"import":                    {}, //
	"in":                        {}, //
	"input":                     {}, //
	"int":                       {}, //
	"is":                        {}, //
	"isinstance":                {}, //
	"issubclass":                {}, //
	"iter":                      {}, //
	"lambda":                    {}, //
	"len":                       {}, //
	"license":                   {}, //
	"list":                      {}, //
	"locals":                    {}, //
	"map":                       {}, //
	"match":                     {}, //
	"max":                       {}, //
	"memoryview":                {}, //
	"min":                       {}, //
	"next":                      {}, //
	"nonlocal":                  {}, //
	"not":                       {}, //
	"object":                    {}, //
	"oct":                       {}, //
	"open":                      {}, //
	"or":                        {}, //
	"ord":                       {}, //
	"pass":                      {}, //
	"pow":                       {}, //
	"print":                     {}, //
	"property":                  {}, //
	"quit":                      {}, //
	"raise":                     {}, //
	"range":                     {}, //
	"repr":                      {}, //
	"return":                    {}, //
	"reversed":                  {}, //
	"round":                     {}, //
	"self":                      {}, //
	"set":                       {}, //
	"setattr":                   {}, //
	"slice":                     {}, //
	"sorted":                    {}, //
	"staticmethod":              {}, //
	"str":                       {}, //
	"sum":                       {}, //
	"super":                     {}, //
	"try":                       {}, //
	"tuple":                     {}, //
	"type":                      {}, //
	"vars":                      {}, //
	"while":                     {}, //
	"with":                      {}, //
	"yield":                     {}, //
	"zip":                       {}, //
	// keep-sorted end
	// LINT.ThenChange(//src/developer/ffx/lib/fuchsia-controller/cpp/fidl_codec/utils.h, //tools/fidl/fidlgen_python/codegen/ir.go, //tools/fidl/gidl/backend/python/conformance.go)
}

func changeIfReserved(s string) string {
	if _, ok := pythonReservedWords[s]; ok {
		return s + "_"
	}
	return s
}

func (c *compiler) compileUnionMember(val fidlgen.UnionMember) PythonUnionMember {
	t := c.compileType(val.Type, val.MaybeFromAlias)
	if t == nil {
		log.Fatalf("Type not supported")
	}
	return PythonUnionMember{
		UnionMember: val,
		PythonType:  *t,
		PythonName:  changeIfReserved(compileSnakeIdentifier(val.Name)),
	}
}

func (c *compiler) compileUnion(val fidlgen.Union) PythonUnion {
	name := *c.compileDeclIdentifier(val.Name)
	python_union := PythonUnion{
		Union:         val,
		Library:       string(val.Name.LibraryName()),
		PythonName:    name,
		PythonMembers: []PythonUnionMember{},
	}

	for _, v := range val.Members {
		member := c.compileUnionMember(v)
		python_union.PythonMembers = append(python_union.PythonMembers, member)
		if python_union.IsResult && member.PythonName == "response" {
			python_union.PythonSuccessType = &member.PythonType
		}
	}

	return python_union
}

func (c *compiler) compilePayload(payload fidlgen.Type) *PythonPayload {
	r := PythonPayload{
		Type:             payload,
		DeclType:         c.decls[payload.Identifier].Type,
		PythonType:       *c.compileType(payload, nil),
		PythonParameters: []PythonParameter{},
	}

	switch r.DeclType {
	case fidlgen.StructDeclType:
		if s, ok := c.PythonRoot.PythonStructs[payload.Identifier]; ok {
			for _, field := range s.PythonMembers {
				r.PythonParameters = append(r.PythonParameters, PythonParameter{
					PythonType:        field.PythonType,
					PythonName:        field.PythonName,
					PythonNoneDefault: false,
				})
			}
		} else if s, ok := c.PythonRoot.ExternalPythonStructs[payload.Identifier]; ok {
			for _, field := range s.PythonMembers {
				r.PythonParameters = append(r.PythonParameters, PythonParameter{
					PythonType:        field.PythonType,
					PythonName:        field.PythonName,
					PythonNoneDefault: false,
				})
			}
		}
	case fidlgen.UnionDeclType:
		if u, ok := c.PythonRoot.PythonUnions[payload.Identifier]; ok {
			for _, field := range u.PythonMembers {
				r.PythonParameters = append(r.PythonParameters, PythonParameter{
					PythonType:        field.PythonType,
					PythonName:        field.PythonName,
					PythonNoneDefault: true,
				})
			}
		}
	case fidlgen.TableDeclType:
		if t, ok := c.PythonRoot.PythonTables[payload.Identifier]; ok {
			for _, field := range t.PythonMembers {
				r.PythonParameters = append(r.PythonParameters, PythonParameter{
					PythonType:        field.PythonType,
					PythonName:        field.PythonName,
					PythonNoneDefault: true,
				})
			}
		}
	default:
		log.Fatalf("Unable to compile payload: %v", payload)
	}

	return &r
}

func (c *compiler) compileProtocol(val fidlgen.Protocol) PythonProtocol {
	name := *c.compileDeclIdentifier(val.Name)
	r := PythonProtocol{
		Protocol:               val,
		PythonName:             name,
		Library:                string(c.library),
		PythonMarkerName:       name + "Marker",
		PythonClientName:       name + "Client",
		PythonServerName:       name + "Server",
		PythonEventHandlerName: name + "EventHandler",
	}

	// Compile the marker for discovering a protocol, if it's discoverable,
	// e.g. "fuchsia.developer.ffx.Echo".
	if _, r.Discoverable = val.LookupAttribute("discoverable"); r.Discoverable {
		r.Marker = strings.Trim(val.GetProtocolName(), "\"")
	} else {
		r.Marker = fmt.Sprintf("(nondiscoverable) %s", val.Name)
	}

	for _, v := range val.Methods {
		m := PythonMethod{
			Method:              v,
			HasFrameworkError:   v.HasFrameworkError(),
			PythonName:          changeIfReserved(compileSnakeIdentifier(v.Name)),
			PythonResponseAlias: changeIfReserved(fmt.Sprintf("%sResponse", compileCamelIdentifier(v.Name))),
		}
		if v.RequestPayload == nil {
			m.PythonRequestPayload = nil
		} else {
			m.PythonRequestPayload = c.compilePayload(*v.RequestPayload)
			m.PythonRequestIdent = m.PythonRequestPayload.PythonType.Identifier
		}
		if v.ResponsePayload == nil {
			m.PythonResponsePayload = nil
		} else {
			m.PythonResponsePayload = c.compilePayload(*v.ResponsePayload)
			m.PythonResponseIdentifier = m.PythonResponsePayload.PythonType.Identifier
		}

		if v.HasError || m.HasFrameworkError {
			m.PythonResponseSuccessPayload = c.compilePayload(*v.ValueType)
		}

		if m.HasResponse &&
			(m.PythonResponsePayload == nil ||
				(m.PythonResponseSuccessPayload != nil &&
					m.PythonResponseSuccessPayload.PythonType.PythonName == "None")) {
			m.EmptyResponse = true
		} else {
			m.EmptyResponse = false
		}

		r.PythonMethods = append(r.PythonMethods, m)
	}

	return r
}

func Compile(root fidlgen.Root) PythonRoot {
	root = root.ForBindings("python")
	root = root.ForTransports([]string{"Channel"})
	c := compiler{
		decls:           root.DeclInfo(),
		library:         root.Name,
		externalModules: map[string]struct{}{},
		PythonRoot: PythonRoot{
			Root:                  root,
			PythonModuleName:      ToPythonModuleName(root.Name),
			EmptySuccessStructs:   map[fidlgen.EncodedCompoundIdentifier]fidlgen.Struct{},
			PythonStructs:         map[fidlgen.EncodedCompoundIdentifier]PythonStruct{},
			ExternalPythonStructs: map[fidlgen.EncodedCompoundIdentifier]PythonStruct{},
			PythonUnions:          map[fidlgen.EncodedCompoundIdentifier]PythonUnion{},
			PythonTables:          map[fidlgen.EncodedCompoundIdentifier]PythonTable{},
		},
	}

	// Collect all empty success structs so that all calls to compileType() will return None as
	// their type.
	for _, v := range root.Structs {
		if v.IsEmptySuccessStruct {
			c.PythonRoot.EmptySuccessStructs[v.Name] = v
		}
	}
	// The only known uses of ExternalStructs are from fuchsia.unknown which provides some empty
	// success structs. Otherwise, it seems safe to ignore types in ExternalStructs.
	for _, v := range root.ExternalStructs {
		if v.IsEmptySuccessStruct {
			c.PythonRoot.EmptySuccessStructs[v.Name] = v
		}
		python_struct, python_unsupported := c.compileStruct(v)
		if python_unsupported != nil {
			c.PythonRoot.PythonUnsupportedTypes = append(c.PythonRoot.PythonUnsupportedTypes, *python_unsupported)
		} else {
			c.PythonRoot.ExternalPythonStructs[v.Name] = python_struct
		}
	}

	for _, v := range root.Tables {
		c.PythonRoot.PythonTables[v.Name] = c.compileTable(v)
	}

	for _, v := range root.Structs {
		if v.IsEmptySuccessStruct {
			c.PythonRoot.EmptySuccessStructs[v.Name] = v
		}
		python_struct, python_unsupported := c.compileStruct(v)
		if python_unsupported != nil {
			c.PythonRoot.PythonUnsupportedTypes = append(c.PythonRoot.PythonUnsupportedTypes, *python_unsupported)
		} else {
			c.PythonRoot.PythonStructs[v.Name] = python_struct
		}
	}

	for _, v := range root.Aliases {
		c.PythonRoot.PythonAliases = append(c.PythonRoot.PythonAliases, c.compileAlias(v))
	}

	// TODO(https://fxbug.dev/396552135): Extend the test suite to cover the different variations
	// of bits declarations.
	for _, v := range root.Bits {
		c.PythonRoot.PythonBits = append(c.PythonRoot.PythonBits, c.compileBits(v))
	}

	for _, v := range root.Consts {
		c.PythonRoot.PythonConsts = append(c.PythonRoot.PythonConsts, c.compileConst(v))
	}

	for _, v := range root.Enums {
		c.PythonRoot.PythonEnums = append(c.PythonRoot.PythonEnums, c.compileEnum(v))
	}

	for _, v := range root.Unions {
		// TODO(https://fxbug.dev/394421154): If v is a result, then its creation should
		// be deferred to when the corresponding protocol method is compiled.
		c.PythonRoot.PythonUnions[v.Name] = c.compileUnion(v)
	}

	for _, v := range root.Protocols {
		c.PythonRoot.PythonProtocols = append(c.PythonRoot.PythonProtocols, c.compileProtocol(v))
	}

	// Sort the external modules to make sure the generated file is
	// consistent across builds.
	var externalModules []string
	for k := range c.externalModules {
		externalModules = append(externalModules, k)
	}
	sort.Strings(externalModules)

	for _, k := range externalModules {
		c.PythonRoot.PythonExternalModules = append(c.PythonRoot.PythonExternalModules, k)
	}

	return c.PythonRoot
}
