// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package resolver

import (
	"fmt"
	"strconv"
	"strings"

	"android.googlesource.com/platform/tools/gpu/api/ast"
	"android.googlesource.com/platform/tools/gpu/api/semantic"
)

func type_(ctx *context, in interface{}) semantic.Type {
	switch in := in.(type) {
	case *ast.Generic:
		return genericType(ctx, in)
	case *ast.IndexedType:
		of := type_(ctx, in.ValueType)
		if in.Index == nil {
			return getSliceType(ctx, in, of)
		}
		size := uint32(0)
		ctx.with(semantic.Uint32Type, func() {
			e := expression(ctx, in.Index)
			if n, ok := e.(semantic.Uint32Value); ok {
				size = uint32(n)
			} else {
				ctx.errorf(in.Index, "Array dimension must be a constant number, got %T", e)
			}
		})
		return getStaticArrayType(ctx, in, of, size)
	case *ast.PointerType:
		to := type_(ctx, in.To)
		return getPointerType(ctx, in, to, in.Const)
	case *ast.Imported:
		return importedType(ctx, in)
	case ast.Node:
		ctx.errorf(in, "Unhandled typeref %T found", in)
		return semantic.VoidType
	default:
		ctx.icef(nil, "Non-node (%T) typeref found", in)
		return semantic.VoidType
	}
}

func genericType(ctx *context, in *ast.Generic) semantic.Type {
	switch in.Name.Value {
	case "map":
		if len(in.Arguments) != 2 {
			ctx.errorf(in, "Map requires 2 args, got %d", len(in.Arguments))
			return semantic.VoidType
		}
		kt := type_(ctx, in.Arguments[0])
		vt := type_(ctx, in.Arguments[1])
		return getMapType(ctx, in, kt, vt)
	case "ref":
		if len(in.Arguments) != 1 {
			ctx.errorf(in, "Ref requires 1 arg, got %d", len(in.Arguments))
			return semantic.VoidType
		}
		vt := type_(ctx, in.Arguments[0])
		return getRefType(ctx, in, vt)
	default:
		if len(in.Arguments) != 0 {
			ctx.errorf(in, "Type %s is not parameterised, got %d", in.Name, len(in.Arguments))
			return semantic.VoidType
		}
		return getSimpleType(ctx, in.Name)
	}
}

func getSimpleType(ctx *context, in *ast.Identifier) semantic.Type {
	name := in.Value
	out := ctx.findType(in, name)
	if out == nil {
		ctx.errorf(in, "Type %s not found", name)
		return semantic.VoidType
	}
	ctx.mappings[in] = out
	if a, ok := out.(*Alias); ok {
		if a.To == nil {
			a.To = type_(ctx, a.AST.To)
		}
		return a.To
	}
	return out
}

func getMapType(ctx *context, at ast.Node, kt, vt semantic.Type) *semantic.Map {
	name := fmt.Sprintf("%sː%sᵐ", strings.Title(kt.Typename()), vt.Typename())
	for _, m := range ctx.api.Maps {
		if m.Name == name {
			if !equal(kt, m.KeyType) {
				ctx.icef(at, "Map %s found with non matching key, got %s expected %s", name, typename(m.KeyType), typename(kt))
			}
			if !equal(vt, m.ValueType) {
				ctx.icef(at, "Map %s found with non matching value, got %s expected %s", name, typename(m.ValueType), typename(vt))
			}
			ctx.mappings[at] = m
			return m
		}
	}
	out := &semantic.Map{
		Name:      name,
		KeyType:   kt,
		ValueType: vt,
		Members:   semantic.Members{},
	}
	ctx.api.Maps = append(ctx.api.Maps, out)
	ctx.mappings[at] = out
	return out
}

func getStaticArrayType(ctx *context, at ast.Node, of semantic.Type, size uint32) *semantic.StaticArray {
	name := fmt.Sprintf("%sː%dᵃ", strings.Title(of.Typename()), size)
	for _, a := range ctx.api.StaticArrays {
		if a.Name == name {
			if !equal(a.ValueType, of) {
				ctx.icef(at, "Static array %s found with non matching value, got %s expected %s",
					a.Name, typename(a.ValueType), typename(of))
			}
			ctx.mappings[at] = a
			return a
		}
	}
	out := &semantic.StaticArray{
		Name:      name,
		ValueType: of,
		Size:      size,
	}
	ctx.api.StaticArrays = append(ctx.api.StaticArrays, out)
	ctx.mappings[at] = out
	return out
}

func getRefType(ctx *context, at ast.Node, to semantic.Type) *semantic.Reference {
	name := strings.Title(to.Typename()) + "ʳ"
	for _, p := range ctx.api.References {
		if p.Name == name {
			if !equal(to, p.To) {
				ctx.icef(at, "ref %s found with non matching value, got %s expected %s", name, typename(p.To), typename(to))
			}
			ctx.mappings[at] = p
			return p
		}
	}
	out := &semantic.Reference{
		Name: name,
		To:   to,
	}
	ctx.api.References = append(ctx.api.References, out)
	ctx.mappings[at] = out
	return out
}

func getPointerType(ctx *context, at ast.Node, to semantic.Type, constant bool) *semantic.Pointer {
	name := strings.Title(to.Typename())
	if constant {
		name += "ᶜ"
	}
	name += "ᵖ"
	for _, p := range ctx.api.Pointers {
		if p.Name == name {
			if !equal(to, p.To) {
				ctx.icef(at, "Pointer %s found with non matching value, got %s expected %s", name, typename(p.To), typename(to))
			}
			ctx.mappings[at] = p
			return p
		}
	}
	out := &semantic.Pointer{
		Name:  name,
		To:    to,
		Const: constant,
	}
	ctx.api.Pointers = append(ctx.api.Pointers, out)
	ctx.mappings[at] = out

	out.Slice = getSliceType(ctx, at, to)

	return out
}

func getSliceType(ctx *context, at ast.Node, to semantic.Type) *semantic.Slice {
	name := strings.Title(to.Typename()) + "ˢ"
	for _, s := range ctx.api.Slices {
		if s.Name == name {
			if !equal(to, s.To) {
				ctx.icef(at, "Slice %s found with non matching value, got %s expected %s", name, typename(s.To), typename(to))
			}
			ctx.mappings[at] = s
			return s
		}
	}
	out := &semantic.Slice{
		Name: name,
		To:   to,
	}
	ctx.api.Slices = append(ctx.api.Slices, out)
	ctx.mappings[at] = out

	out.Pointer = getPointerType(ctx, at, to, false)

	return out
}

func enum(ctx *context, out *semantic.Enum) {
	if len(out.AllEntries) > 0 {
		// Already resolved.
		return
	}
	in := out.AST
	out.Docs = findDocumentation(in.CST)
	out.Annotations = annotations(ctx, in.Annotations)
	out.IsBitfield = in.IsBitfield
	for _, e := range in.Entries {
		v, err := strconv.ParseUint(e.Value.Value, 0, 32)
		if err != nil {
			ctx.errorf(e, "could not parse %s as uint32", e.Value)
			continue
		}
		entry := &semantic.EnumEntry{
			AST:   e,
			Enum:  out,
			Name:  e.Name.Value,
			Docs:  findDocumentation(e.CST),
			Value: uint32(v),
		}
		out.Entries = append(out.Entries, entry)
		out.AllEntries = append(out.AllEntries, entry)
		ctx.mappings[e] = entry
	}
	for _, extends := range in.Extends {
		t := ctx.findType(extends, extends.Value)
		if e, ok := t.(*semantic.Enum); !ok {
			ctx.errorf(extends, "non enum entry %s in extension list", typename(t))
		} else {
			out.Extends = append(out.Extends, e)
			enum(ctx, e)
			for _, entry := range e.AllEntries {
				copy := *entry
				copy.Enum = out
				out.AllEntries = append(out.AllEntries, &copy)
			}
			ctx.mappings[extends] = e
		}
	}
	for _, entry := range out.AllEntries {
		ctx.add(entry.Name, entry)
	}
	ctx.mappings[in] = out
}

func class(ctx *context, out *semantic.Class) {
	in := out.AST
	out.Docs = findDocumentation(in.CST)
	out.Annotations = annotations(ctx, in.Annotations)
	for _, extends := range in.Extends {
		t := ctx.findType(extends, extends.Value)
		if c, ok := t.(*semantic.Class); !ok {
			ctx.errorf(extends, "non class entry %s in extension list", typename(t))
		} else {
			out.Extends = append(out.Extends, c)
			c.ExtendedBy = append(c.ExtendedBy, out)
			ctx.mappings[extends] = c
		}
	}
	out.Fields = make([]*semantic.Field, len(in.Fields))
	for i, f := range in.Fields {
		field := field(ctx, f, out)
		out.Fields[i] = field
		out.Members[field.Name] = field
	}
	ctx.mappings[in] = out
}

func field(ctx *context, in *ast.Field, class *semantic.Class) *semantic.Field {
	out := &semantic.Field{AST: in, Name: in.Name.Value, Class: class}
	out.Docs = findDocumentation(in.CST)
	out.Annotations = annotations(ctx, in.Annotations)
	out.Type = type_(ctx, in.Type)
	if isVoid(out.Type) {
		ctx.errorf(in, "void typed field %s on class %s", out.Name, out.Class.Name)
	}
	if in.Default != nil {
		ctx.with(out.Type, func() {
			out.Default = expression(ctx, in.Default)
		})
		dt := out.Default.ExpressionType()
		if !assignable(out.Type, dt) {
			ctx.errorf(in, "cannot assign %s to %s", typename(dt), typename(out.Type))
		}
	}
	ctx.mappings[in] = out
	return out
}

func pseudonym(ctx *context, out *semantic.Pseudonym) {
	in := out.AST
	out.Docs = findDocumentation(in.CST)
	out.Annotations = annotations(ctx, in.Annotations)
	out.To = type_(ctx, in.To)
}

func importedType(ctx *context, in *ast.Imported) semantic.Type {
	api, ok := ctx.get(in, in.From.Value).(*semantic.API)
	if !ok {
		ctx.errorf(in, "%s not an imported api", in.From.Value)
		return semantic.VoidType
	}
	t, ok := api.Member(in.Name.Value).(semantic.Type)
	if !ok {
		ctx.errorf(in, "%s not a type in %s", in.Name.Value, in.From.Value)
		return semantic.VoidType
	}
	return t
}

func typename(e semantic.Type) string {
	if e == nil {
		return "missing"
	} else {
		return e.Typename()
	}
}
