// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package sem

import (
	"fmt"
	"sort"

	"dawn.googlesource.com/dawn/tools/src/container"
	"dawn.googlesource.com/dawn/tools/src/tint/intrinsic/ast"
)

// Sem is the root of the semantic tree
type Sem struct {
	Enums                     []*Enum
	Types                     []*Type
	TypeMatchers              []*TypeMatcher
	EnumMatchers              []*EnumMatcher
	Builtins                  []*Intrinsic
	UnaryOperators            []*Intrinsic
	BinaryOperators           []*Intrinsic
	ConstructorsAndConverters []*Intrinsic
	// Maximum number of template types used across all builtins
	MaxTemplates int
	// The alphabetically sorted list of unique parameter names
	UniqueParameterNames []string
}

// Enum returns the enum with the given name
func (s *Sem) Enum(name string) *Enum {
	for _, e := range s.Enums {
		if e.Name == name {
			return e
		}
	}
	return nil
}

// New returns a new Sem
func New() *Sem {
	return &Sem{
		Enums:           []*Enum{},
		Types:           []*Type{},
		TypeMatchers:    []*TypeMatcher{},
		EnumMatchers:    []*EnumMatcher{},
		Builtins:        []*Intrinsic{},
		UnaryOperators:  []*Intrinsic{},
		BinaryOperators: []*Intrinsic{},
	}
}

// Enum describes an enumerator
type Enum struct {
	Decl    ast.EnumDecl
	Name    string
	Entries []*EnumEntry
}

// FindEntry returns the enum entry with the given name
func (e *Enum) FindEntry(name string) *EnumEntry {
	for _, entry := range e.Entries {
		if entry.Name == name {
			return entry
		}
	}
	return nil
}

// PublicEntries returns the enum entries that are not annotated with @internal
func (e *Enum) PublicEntries() []*EnumEntry {
	out := make([]*EnumEntry, 0, len(e.Entries))
	for _, entry := range e.Entries {
		if !entry.IsInternal {
			out = append(out, entry)
		}
	}
	return out
}

// NameSet returns a set of all the enum entry names
func (e *Enum) NameSet() container.Set[string] {
	out := container.NewSet[string]()
	for _, entry := range e.Entries {
		out.Add(entry.Name)
	}
	return out
}

// EnumEntry is an entry in an enumerator
type EnumEntry struct {
	Enum       *Enum
	Name       string
	IsInternal bool // True if this entry is not part of the WGSL grammar
}

// Format implements the fmt.Formatter interface
func (e EnumEntry) Format(w fmt.State, verb rune) {
	if e.IsInternal {
		fmt.Fprint(w, "[[internal]] ")
	}
	fmt.Fprint(w, e.Name)
}

// Type declares a type
type Type struct {
	TemplateParams []TemplateParam
	Decl           ast.TypeDecl
	Name           string
	DisplayName    string
	Precedence     int
}

// TypeMatcher declares a type matcher
type TypeMatcher struct {
	TemplateParams []TemplateParam
	Decl           ast.MatcherDecl
	Name           string
	Types          []*Type
}

func (t TypeMatcher) PrecedenceSortedTypes() []*Type {
	out := make([]*Type, len(t.Types))
	copy(out, t.Types)
	sort.Slice(out, func(i, j int) bool { return out[i].Precedence > out[j].Precedence })
	return out
}

// EnumMatcher declares a enum matcher
type EnumMatcher struct {
	TemplateParams []TemplateParam
	Decl           ast.MatcherDecl
	Name           string
	Enum           *Enum
	Options        []*EnumEntry
}

// TemplateKind is an enumerator of template kinds.
type TemplateKind string

const (
	// A templated type
	TypeTemplate TemplateKind = "Type"
	// A templated number
	NumberTemplate TemplateKind = "Number"
)

// TemplateTypeParam is a template type parameter
type TemplateTypeParam struct {
	Name     string
	ASTParam ast.TemplateParam
	Type     *FullyQualifiedName
}

func (t *TemplateTypeParam) AST() ast.TemplateParam     { return t.ASTParam }
func (t *TemplateTypeParam) TemplateKind() TemplateKind { return TypeTemplate }

// Format implements the fmt.Formatter interface
func (t *TemplateTypeParam) Format(w fmt.State, verb rune) {
	fmt.Fprint(w, t.Name)
	if t.Type != nil {
		fmt.Fprint(w, ": ")
		fmt.Fprint(w, *t.Type)
	}
}

// TemplateEnumParam is a template enum parameter
type TemplateEnumParam struct {
	Name     string
	ASTParam ast.TemplateParam
	Enum     *Enum
	Matcher  *EnumMatcher // Optional
}

func (t *TemplateEnumParam) AST() ast.TemplateParam     { return t.ASTParam }
func (t *TemplateEnumParam) TemplateKind() TemplateKind { return NumberTemplate }

// Format implements the fmt.Formatter interface
func (t *TemplateEnumParam) Format(w fmt.State, verb rune) {
	fmt.Fprint(w, t.Name)
	if t.Enum != nil {
		fmt.Fprint(w, ": ")
		fmt.Fprint(w, *t.Enum)
	}
}

// TemplateNumberParam is a template type parameter
type TemplateNumberParam struct {
	Name     string
	ASTParam ast.TemplateParam
}

func (t *TemplateNumberParam) AST() ast.TemplateParam     { return t.ASTParam }
func (t *TemplateNumberParam) TemplateKind() TemplateKind { return NumberTemplate }

// Format implements the fmt.Formatter interface
func (t *TemplateNumberParam) Format(w fmt.State, verb rune) {
	fmt.Fprint(w, t.Name)
	fmt.Fprint(w, ": num")
}

// Intrinsic describes the overloads of a builtin or operator
type Intrinsic struct {
	Name      string
	Overloads []*Overload
}

// IntrinsicTemplates is a list of TemplateParam, used by an Intrinsic.
type IntrinsicTemplates []TemplateParam

// Types() returns all the template type parameters
func (t IntrinsicTemplates) Types() []*TemplateTypeParam {
	out := []*TemplateTypeParam{}
	for _, p := range t {
		if ty, ok := p.(*TemplateTypeParam); ok {
			out = append(out, ty)
		}
	}
	return out
}

// Numbers() returns all the template number parameters.
func (t IntrinsicTemplates) Numbers() []TemplateParam {
	out := []TemplateParam{}
	for _, p := range t {
		if _, ok := p.(*TemplateTypeParam); !ok {
			out = append(out, p)
		}
	}
	return out
}

// Overload describes a single overload of a builtin or operator
type Overload struct {
	Decl              ast.IntrinsicDecl
	Intrinsic         *Intrinsic
	ExplicitTemplates IntrinsicTemplates
	ImplicitTemplates IntrinsicTemplates
	ReturnType        *FullyQualifiedName
	Parameters        []Parameter
	CanBeUsedInStage  StageUses
	MustUse           bool   // True if function cannot be used as a statement
	MemberFunction    bool   // True if function is a member function
	IsDeprecated      bool   // True if this overload is deprecated
	ConstEvalFunction string // Name of the function used to evaluate the intrinsic at shader creation time
}

// AllTemplates returns the combined list of explicit and implicit templates
func (o *Overload) AllTemplates() IntrinsicTemplates {
	return append(append([]TemplateParam{}, o.ExplicitTemplates...), o.ImplicitTemplates...)
}

// StageUses describes the stages an overload can be used in
type StageUses struct {
	Vertex   bool
	Fragment bool
	Compute  bool
}

// List returns the stage uses as a string list
func (u StageUses) List() []string {
	out := []string{}
	if u.Vertex {
		out = append(out, "vertex")
	}
	if u.Fragment {
		out = append(out, "fragment")
	}
	if u.Compute {
		out = append(out, "compute")
	}
	return out
}

// Format implements the fmt.Formatter interface
func (o Overload) Format(w fmt.State, verb rune) {
	switch o.Decl.Kind {
	case ast.Builtin:
		fmt.Fprintf(w, "fn ")
	case ast.Operator:
		fmt.Fprintf(w, "op ")
	}
	fmt.Fprintf(w, "%v", o.Intrinsic.Name)
	if len(o.ExplicitTemplates) > 0 {
		fmt.Fprintf(w, "<")
		formatList(w, o.ExplicitTemplates)
		fmt.Fprintf(w, ">")
	}
	if len(o.ImplicitTemplates) > 0 {
		fmt.Fprintf(w, "[")
		formatList(w, o.ImplicitTemplates)
		fmt.Fprintf(w, "]")
	}
	fmt.Fprint(w, "(")
	for i, p := range o.Parameters {
		if i > 0 {
			fmt.Fprint(w, ", ")
		}
		fmt.Fprintf(w, "%v", p)
	}
	fmt.Fprint(w, ")")
	if o.ReturnType != nil {
		fmt.Fprintf(w, " -> %v", o.ReturnType)
	}
}

// Parameter describes a single parameter of a function overload
type Parameter struct {
	Name      string
	Type      FullyQualifiedName
	IsConst   bool    // Did this parameter have a @const attribute?
	TestValue float64 // Value to use for end-to-end tests
}

// Format implements the fmt.Formatter interface
func (p Parameter) Format(w fmt.State, verb rune) {
	if p.IsConst {
		fmt.Fprint(w, "@const ")
	}
	if p.Name != "" {
		fmt.Fprintf(w, "%v: ", p.Name)
	}
	fmt.Fprintf(w, "%v", p.Type)
}

// FullyQualifiedName is the usage of a Type, TypeMatcher or TemplateTypeParam
type FullyQualifiedName struct {
	Target            Named
	TemplateArguments []interface{}
}

// Format implements the fmt.Formatter interface
func (f FullyQualifiedName) Format(w fmt.State, verb rune) {
	fmt.Fprint(w, f.Target.GetName())
	if len(f.TemplateArguments) > 0 {
		fmt.Fprintf(w, "<")
		formatList(w, f.TemplateArguments)
		fmt.Fprintf(w, ">")
	}
}

// TemplateParam is a TemplateEnumParam, TemplateTypeParam or TemplateNumberParam
type TemplateParam interface {
	Named
	TemplateKind() TemplateKind
	AST() ast.TemplateParam
}

// ResolvableType is a Type, TypeMatcher or TemplateTypeParam
type ResolvableType interface {
	Named
	isResolvableType()
}

func (*Type) isResolvableType()              {}
func (*TypeMatcher) isResolvableType()       {}
func (*TemplateTypeParam) isResolvableType() {}

// Named is something that can be looked up by name
type Named interface {
	isNamed()
	GetName() string
}

func (*Enum) isNamed()                {}
func (*EnumEntry) isNamed()           {}
func (*Type) isNamed()                {}
func (*TypeMatcher) isNamed()         {}
func (*EnumMatcher) isNamed()         {}
func (*TemplateTypeParam) isNamed()   {}
func (*TemplateEnumParam) isNamed()   {}
func (*TemplateNumberParam) isNamed() {}

// GetName returns the name of the Enum
func (e *Enum) GetName() string { return e.Name }

// GetName returns the name of the EnumEntry
func (e *EnumEntry) GetName() string { return e.Name }

// GetName returns the name of the Type
func (t *Type) GetName() string { return t.Name }

// GetName returns the name of the TypeMatcher
func (t *TypeMatcher) GetName() string { return t.Name }

// GetName returns the name of the EnumMatcher
func (e *EnumMatcher) GetName() string { return e.Name }

// GetName returns the name of the TemplateTypeParam
func (t *TemplateTypeParam) GetName() string { return t.Name }

// GetName returns the name of the TemplateEnumParam
func (t *TemplateEnumParam) GetName() string { return t.Name }

// GetName returns the name of the TemplateNumberParam
func (t *TemplateNumberParam) GetName() string { return t.Name }

func formatList[T any](w fmt.State, list []T) {
	for i, v := range list {
		if i > 0 {
			fmt.Fprint(w, ", ")
		}
		fmt.Fprintf(w, "%v", v)
	}
}
