// Copyright 2021 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 fidlgen_cpp

import (
	"fmt"
	"strings"

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

//
// Generate code for sending and receiving FIDL messages i.e. the messaging API.
//

// hlMessagingDetails represents the various generated definitions associated
// with a protocol, in the high-level C++ bindings.
// TODO(fxbug.dev/72798): Use the same approach to pass wireTypeNames and
// hlMessagingDetails to the templates.
type hlMessagingDetails struct {
	// ProtocolMarker is a pure-virtual interface corresponding to methods in
	// the protocol. Notably, HLCPP shares the same interface type between
	// the server and client bindings API.
	ProtocolMarker Name

	// InterfaceAliasForStub is the type alias generated within the
	// "Stub" class, that refers to the pure-virtual interface corresponding to
	// the protocol.
	InterfaceAliasForStub Name

	// Proxy implements the interface by encoding and making method calls.
	Proxy Name

	// Stub calls into the interface after decoding an incoming message.
	// It also implements the EventSender interface.
	Stub Name

	// EventSender is a pure-virtual interface for sending events.
	EventSender Name

	// SyncInterface is a pure-virtual interface for making synchronous calls.
	SyncInterface Name

	// SyncProxy implements the SyncInterface.
	SyncProxy Name

	RequestEncoder  Name
	RequestDecoder  Name
	ResponseEncoder Name
	ResponseDecoder Name
}

func compileHlMessagingDetails(protocol NameVariants) hlMessagingDetails {
	p := protocol.Natural
	stub := p.AppendName("_Stub")
	return hlMessagingDetails{
		ProtocolMarker:        p,
		InterfaceAliasForStub: stub.Nest(p.AppendName("_clazz").Name()),
		Proxy:                 p.AppendName("_Proxy"),
		Stub:                  stub,
		EventSender:           p.AppendName("_EventSender"),
		SyncInterface:         p.AppendName("_Sync"),
		SyncProxy:             p.AppendName("_SyncProxy"),
		RequestEncoder:        p.AppendName("_RequestEncoder"),
		RequestDecoder:        p.AppendName("_RequestDecoder"),
		ResponseEncoder:       p.AppendName("_ResponseEncoder"),
		ResponseDecoder:       p.AppendName("_ResponseDecoder"),
	}
}

type protocolWithHlMessaging struct {
	Protocol
	hlMessagingDetails
}

// WithHlMessaging returns a new protocol IR where the HLCPP bindings details
// are promoted to the same naming scope as the protocol. This makes it easier
// to access the HLCPP details in golang templates.
func (p Protocol) WithHlMessaging() protocolWithHlMessaging {
	return protocolWithHlMessaging{
		Protocol:           p,
		hlMessagingDetails: p.hlMessaging,
	}
}

// TODO(fxbug.dev/60240): Start implementing unified bindings messaging layer
// based on this skeleton.
type unifiedMessagingDetails struct {
	ClientImpl      Name
	EventHandlers   Name
	Interface       Name
	EventSender     Name
	RequestEncoder  Name
	RequestDecoder  Name
	ResponseEncoder Name
	ResponseDecoder Name
}

// These correspond to templated classes forward-declared in
// //zircon/system/ulib/fidl/include/lib/fidl/llcpp/wire_messaging.h
var (
	// Protocol related
	WireSyncClient            = fidlNs.Member("WireSyncClient")
	WireClient                = fidlNs.Member("WireClient")
	WireEventHandlerInterface = internalNs.Member("WireEventHandlerInterface")
	WireSyncEventHandler      = fidlNs.Member("WireSyncEventHandler")
	WireAsyncEventHandler     = fidlNs.Member("WireAsyncEventHandler")
	WireInterface             = fidlNs.Member("WireInterface")
	WireRawChannelInterface   = fidlNs.Member("WireRawChannelInterface")
	WireEventSender           = fidlNs.Member("WireEventSender")
	WireWeakEventSender       = internalNs.Member("WireWeakEventSender")
	WireClientImpl            = internalNs.Member("WireClientImpl")
	WireCaller                = internalNs.Member("WireCaller")
	WireDispatcher            = internalNs.Member("WireDispatcher")

	// MethodRelated
	WireRequest         = fidlNs.Member("WireRequest")
	WireResponse        = fidlNs.Member("WireResponse")
	WireResult          = fidlNs.Member("WireResult")
	WireUnownedResult   = fidlNs.Member("WireUnownedResult")
	WireResponseContext = fidlNs.Member("WireResponseContext")
)

type wireTypeNames struct {
	// WireProtocolMarker is a class only used for containing other definitions
	// related to this protocol.
	// TODO(fxbug.dev/72798): Golang template should use this instead of the
	// NameVariants embedded in Protocol.
	WireProtocolMarker        Name
	WireSyncClient            Name
	WireClient                Name
	WireEventHandlerInterface Name
	WireSyncEventHandler      Name
	WireAsyncEventHandler     Name
	WireInterface             Name
	WireRawChannelInterface   Name
	WireEventSender           Name
	WireWeakEventSender       Name
	WireClientImpl            Name
	WireCaller                Name
	WireDispatcher            Name
}

func newWireTypeNames(protocolVariants NameVariants) wireTypeNames {
	p := protocolVariants.Wire
	return wireTypeNames{
		WireProtocolMarker:        p,
		WireSyncClient:            WireSyncClient.Template(p),
		WireClient:                WireClient.Template(p),
		WireEventHandlerInterface: WireEventHandlerInterface.Template(p),
		WireSyncEventHandler:      WireSyncEventHandler.Template(p),
		WireAsyncEventHandler:     WireAsyncEventHandler.Template(p),
		WireInterface:             WireInterface.Template(p),
		WireRawChannelInterface:   WireRawChannelInterface.Template(p),
		WireEventSender:           WireEventSender.Template(p),
		WireWeakEventSender:       WireWeakEventSender.Template(p),
		WireClientImpl:            WireClientImpl.Template(p),
		WireCaller:                WireCaller.Template(p),
		WireDispatcher:            WireDispatcher.Template(p),
	}
}

// protocolInner contains information about a Protocol that should be
// filled out by the compiler.
type protocolInner struct {
	Attributes
	// TODO(fxbug.dev/72798): This should be replaced by ProtocolMarker in hlMessagingDetails
	// and wireMessagingDetails. In particular, the unified bindings do not declare
	// protocol marker classes.
	NameVariants

	// [Discoverable] protocols are exported to the outgoing namespace under this
	// name. This is deprecated by FTP-041 unified services.
	// TODO(fxbug.dev/8035): Remove.
	DiscoverableName string

	hlMessaging hlMessagingDetails
	wireTypeNames

	// ClientAllocation is the allocation behavior of the client when receiving
	// FIDL events over this protocol.
	SyncEventAllocation allocation
	Methods             []Method
	FuzzingName         string
	TestBase            NameVariants
}

// Protocol should be created using newProtocol.
type Protocol struct {
	protocolInner

	// OneWayMethods contains the list of one-way (i.e. fire-and-forget) methods
	// in the protocol.
	OneWayMethods []*Method

	// TwoWayMethods contains the list of two-way (i.e. has both request and
	// response) methods in the protocol.
	TwoWayMethods []*Method

	// ClientMethods contains the list of client-initiated methods (i.e. any
	// interaction that is not an event). It is the union of one-way and two-way
	// methods.
	ClientMethods []*Method

	// Events contains the list of events (i.e. initiated by servers)
	// in the protocol.
	Events []*Method

	// Generated struct holding variant-agnostic details about protocol.
	ProtocolDetails Name
}

func (Protocol) Kind() declKind {
	return Kinds.Protocol
}

var _ Kinded = (*Protocol)(nil)

func (p Protocol) Name() string {
	return p.Wire.Name() // TODO: not the wire name, maybe?
}

func (p Protocol) NaturalType() string {
	return p.Natural.String()
}

func (p Protocol) WireType() string {
	return p.Wire.String()
}

func newProtocol(inner protocolInner) Protocol {
	type kinds []methodKind

	filterBy := func(kinds kinds) []*Method {
		var out []*Method
		for i := 0; i < len(inner.Methods); i++ {
			m := &inner.Methods[i]
			k := m.methodKind()
			for _, want := range kinds {
				if want == k {
					out = append(out, m)
				}
			}
		}
		return out
	}

	return Protocol{
		protocolInner:   inner,
		OneWayMethods:   filterBy(kinds{oneWayMethod}),
		TwoWayMethods:   filterBy(kinds{twoWayMethod}),
		ClientMethods:   filterBy(kinds{oneWayMethod, twoWayMethod}),
		Events:          filterBy(kinds{eventMethod}),
		ProtocolDetails: MakeName("fidl::internal::ProtocolDetails").Template(inner.Wire),
	}
}

type argsWrapper []Parameter

// TODO(fxb/7704): We should be able to remove as we align with args with struct
// representation.
func (args argsWrapper) isResource() bool {
	for _, arg := range args {
		if arg.Type.IsResource {
			return true
		}
	}
	return false
}

type messageInner struct {
	fidlgen.TypeShape
	HlCodingTable   Name
	WireCodingTable Name
}

// message contains lower level wire-format information about a request/response
// message.
// message should be created using newMessage.
type message struct {
	messageInner
	fidlgen.Strictness
	IsResource       bool
	ClientAllocation allocation
	ServerAllocation allocation
}

// methodContext indicates where the request/response is used.
// The allocation strategies differ for client and server contexts, in LLCPP.
type methodContext int

const (
	_ methodContext = iota
	clientContext
	serverContext
)

type boundednessQuery func(methodContext, fidlgen.Strictness) boundedness

func newMessage(inner messageInner, args []Parameter, wire wireTypeNames,
	direction messageDirection) message {
	ts := inner.TypeShape
	strictness := fidlgen.Strictness(!ts.HasFlexibleEnvelope)
	return message{
		messageInner: inner,
		Strictness:   strictness,
		IsResource:   argsWrapper(args).isResource(),
		ClientAllocation: computeAllocation(
			ts.InlineSize,
			ts.MaxOutOfLine,
			direction.queryBoundedness(clientContext, strictness)),
		ServerAllocation: computeAllocation(
			ts.InlineSize,
			ts.MaxOutOfLine,
			direction.queryBoundedness(serverContext, strictness)),
	}
}

func (m message) HasPointer() bool {
	return m.Depth > 0
}

type wireMethod struct {
	WireCompleter       Name
	WireCompleterBase   Name
	WireRequest         Name
	WireResponse        Name
	WireResponseContext Name
	WireResult          Name
	WireUnownedResult   Name
}

func newWireMethod(name string, wireTypes wireTypeNames, protocolMarker Name, methodMarker Name) wireMethod {
	i := wireTypes.WireInterface.Nest(name)
	return wireMethod{
		WireCompleter:       i.AppendName("Completer"),
		WireCompleterBase:   i.AppendName("CompleterBase"),
		WireRequest:         WireRequest.Template(methodMarker),
		WireResponse:        WireResponse.Template(methodMarker),
		WireResponseContext: WireResponseContext.Template(methodMarker),
		WireResult:          WireResult.Template(methodMarker),
		WireUnownedResult:   WireUnownedResult.Template(methodMarker),
	}
}

// methodInner contains information about a Method that should be filled out by
// the compiler.
type methodInner struct {
	protocolName NameVariants
	Marker       NameVariants
	wireMethod
	baseCodingTableName string
	requestTypeShape    fidlgen.TypeShape
	responseTypeShape   fidlgen.TypeShape

	Attributes
	Name         string
	Ordinal      uint64
	HasRequest   bool
	RequestArgs  []Parameter
	HasResponse  bool
	ResponseArgs []Parameter
	Transitional bool
	Result       *Result
}

// Method should be created using newMethod.
type Method struct {
	methodInner
	NameInLowerSnakeCase string
	OrdinalName          NameVariants
	Request              message
	Response             message
	CallbackType         string
	ResponseHandlerType  string
	ResponderType        string
	// Protocol is a reference to the containing protocol, for the
	// convenience of golang templates.
	Protocol *Protocol
}

type messageDirection int

const (
	_ messageDirection = iota
	messageDirectionRequest
	messageDirectionResponse
)

// Compute boundedness based on client/server, request/response, and strictness.
func (d messageDirection) queryBoundedness(c methodContext, s fidlgen.Strictness) boundedness {
	switch d {
	case messageDirectionRequest:
		if c == clientContext {
			// Allocation is bounded when sending request from a client.
			return boundednessBounded
		} else {
			return boundedness(s.IsStrict())
		}
	case messageDirectionResponse:
		if c == serverContext {
			// Allocation is bounded when sending response from a server.
			return boundednessBounded
		} else {
			return boundedness(s.IsStrict())
		}
	}
	panic(fmt.Sprintf("unexpected message direction: %v", d))
}

func newMethod(inner methodInner, hl hlMessagingDetails, wire wireTypeNames) Method {
	hlCodingTableBase := hl.ProtocolMarker.Namespace().Append("_internal").Member(inner.baseCodingTableName)
	wireCodingTableBase := wire.WireProtocolMarker.Namespace().Member(inner.baseCodingTableName)

	hlRequestCodingTable := hlCodingTableBase.AppendName("RequestTable")
	wireRequestCodingTable := wireCodingTableBase.AppendName("RequestTable")
	hlResponseCodingTable := hlCodingTableBase.AppendName("ResponseTable")
	wireResponseCodingTable := wireCodingTableBase.AppendName("ResponseTable")
	if !inner.HasRequest {
		hlResponseCodingTable = hlCodingTableBase.AppendName("EventTable")
		wireResponseCodingTable = wireCodingTableBase.AppendName("EventTable")
	}

	callbackType := ""
	if inner.HasResponse {
		callbackType = changeIfReserved(fidlgen.Identifier(inner.Name + "Callback"))
	}
	ordinalName := fmt.Sprintf("k%s_%s_Ordinal", inner.protocolName.Natural.Name(), inner.Name)

	m := Method{
		methodInner:          inner,
		NameInLowerSnakeCase: fidlgen.ToSnakeCase(inner.Name),
		OrdinalName: NameVariants{
			Natural: inner.protocolName.Natural.Namespace().Append("internal").Member(ordinalName),
			Wire:    inner.protocolName.Wire.Namespace().Member(ordinalName),
		},
		Request: newMessage(messageInner{
			TypeShape:       inner.requestTypeShape,
			HlCodingTable:   hlRequestCodingTable,
			WireCodingTable: wireRequestCodingTable,
		}, inner.RequestArgs, wire, messageDirectionRequest),
		Response: newMessage(messageInner{
			TypeShape:       inner.responseTypeShape,
			HlCodingTable:   hlResponseCodingTable,
			WireCodingTable: wireResponseCodingTable,
		}, inner.ResponseArgs, wire, messageDirectionResponse),
		CallbackType:        callbackType,
		ResponseHandlerType: fmt.Sprintf("%s_%s_ResponseHandler", inner.protocolName.Natural.Name(), inner.Name),
		ResponderType:       fmt.Sprintf("%s_%s_Responder", inner.protocolName.Natural.Name(), inner.Name),
		Protocol:            nil,
	}
	return m
}

type methodKind int

const (
	oneWayMethod = methodKind(iota)
	twoWayMethod
	eventMethod
)

func (m *Method) methodKind() methodKind {
	if m.HasRequest {
		if m.HasResponse {
			return twoWayMethod
		}
		return oneWayMethod
	}
	if !m.HasResponse {
		panic("A method should have at least either a request or a response")
	}
	return eventMethod
}

func (m *Method) CallbackWrapper() string {
	return "fit::function"
}

type Parameter struct {
	Type              Type
	Name              string
	Offset            int
	HandleInformation *HandleInformation
}

func (p Parameter) NameAndType() (string, Type) {
	return p.Name, p.Type
}

func allEventsStrict(methods []Method) fidlgen.Strictness {
	strictness := fidlgen.IsStrict
	for _, m := range methods {
		if !m.HasRequest && m.HasResponse && m.Response.IsFlexible() {
			strictness = fidlgen.IsFlexible
			break
		}
	}
	return strictness
}

func (c *compiler) compileProtocol(p fidlgen.Protocol) Protocol {
	protocolName := c.compileNameVariants(p.Name)
	codingTableName := codingTableName(p.Name)
	hlMessaging := compileHlMessagingDetails(protocolName)
	wireTypeNames := newWireTypeNames(protocolName)

	methods := []Method{}
	for _, v := range p.Methods {
		name := changeIfReserved(v.Name)

		var result *Result
		if v.MethodResult != nil {
			// If the method uses the error syntax, Response[0] will be a union
			// that was placed in c.resultForUnion. Otherwise, this will be nil.
			result = c.resultForUnion[v.Response[0].Type.Identifier]
		}

		methodMarker := protocolName.Nest(name)

		method := newMethod(methodInner{
			protocolName: protocolName,
			// Using the raw identifier v.Name instead of the name after
			// reserved words logic, since that's the behavior in fidlc.
			baseCodingTableName: codingTableName + string(v.Name),
			Marker:              methodMarker,
			requestTypeShape:    v.RequestTypeShapeV1,
			responseTypeShape:   v.ResponseTypeShapeV1,
			wireMethod:          newWireMethod(name, wireTypeNames, protocolName.Wire, methodMarker.Wire),
			Attributes:          Attributes{v.Attributes},
			Name:                name,
			Ordinal:             v.Ordinal,
			HasRequest:          v.HasRequest,
			RequestArgs:         c.compileParameterArray(v.Request),
			HasResponse:         v.HasResponse,
			ResponseArgs:        c.compileParameterArray(v.Response),
			Transitional:        v.IsTransitional(),
			Result:              result,
		}, hlMessaging, wireTypeNames)
		methods = append(methods, method)
	}

	var maxResponseSize int
	for _, method := range methods {
		if size := method.Response.InlineSize + method.Response.MaxOutOfLine; size > maxResponseSize {
			maxResponseSize = size
		}
	}

	fuzzingName := strings.ReplaceAll(strings.ReplaceAll(string(p.Name), ".", "_"), "/", "_")
	r := newProtocol(protocolInner{
		Attributes:       Attributes{p.Attributes},
		NameVariants:     protocolName,
		hlMessaging:      hlMessaging,
		wireTypeNames:    wireTypeNames,
		DiscoverableName: p.GetServiceName(),
		SyncEventAllocation: computeAllocation(
			maxResponseSize, 0, messageDirectionResponse.queryBoundedness(
				clientContext, allEventsStrict(methods))),
		Methods:     methods,
		FuzzingName: fuzzingName,
		TestBase:    protocolName.AppendName("_TestBase").AppendNamespace("testing"),
	})
	for i := 0; i < len(methods); i++ {
		methods[i].Protocol = &r
	}
	return r
}

func (c *compiler) compileParameterArray(val []fidlgen.Parameter) []Parameter {
	var params []Parameter = []Parameter{}
	for _, v := range val {
		params = append(params, Parameter{
			Type:              c.compileType(v.Type),
			Name:              changeIfReserved(v.Name),
			Offset:            v.FieldShapeV1.Offset,
			HandleInformation: c.fieldHandleInformation(&v.Type),
		})
	}
	return params
}

//
// Functions for calculating message buffer size bounds
//

func fidlAlign(size int) int {
	return (size + 7) & ^7
}

type boundedness bool

const (
	boundednessBounded   = true
	boundednessUnbounded = false
)

// This value needs to be kept in sync with the one defined in
// zircon/system/ulib/fidl/include/lib/fidl/llcpp/sync_call.h
const llcppMaxStackAllocSize = 512
const channelMaxMessageSize = 65536

// allocation describes the allocation strategy of some operation, such as
// sending requests, receiving responses, or handling events. Note that the
// allocation strategy may depend on client/server context, direction of the
// message, and the content/shape of the message, as we make optimizations.
type allocation struct {
	IsStack bool
	Size    int

	bufferType bufferType
	size       string
}

func (alloc allocation) ByteBufferType() string {
	switch alloc.bufferType {
	case inlineBuffer:
		return fmt.Sprintf("::fidl::internal::InlineMessageBuffer<%s>", alloc.size)
	case boxedBuffer:
		return fmt.Sprintf("::fidl::internal::BoxedMessageBuffer<%s>", alloc.size)
	}
	panic(fmt.Sprintf("unexpected buffer type: %v", alloc.bufferType))
}

type bufferType int

const (
	_ bufferType = iota
	inlineBuffer
	boxedBuffer
)

func computeAllocation(primarySize int, maxOutOfLine int, boundedness boundedness) allocation {
	var sizeString string
	var size int
	if boundedness == boundednessUnbounded || primarySize+maxOutOfLine > channelMaxMessageSize {
		sizeString = "ZX_CHANNEL_MAX_MSG_BYTES"
		size = channelMaxMessageSize
	} else {
		size = fidlAlign(primarySize + maxOutOfLine)
		sizeString = fmt.Sprintf("%d", size)
	}

	if size > llcppMaxStackAllocSize {
		return allocation{
			IsStack:    false,
			Size:       0,
			bufferType: boxedBuffer,
			size:       sizeString,
		}
	} else {
		return allocation{
			IsStack:    true,
			Size:       size,
			bufferType: inlineBuffer,
			size:       sizeString,
		}
	}
}
