// Copyright 2020 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 analysis

import (
	"fmt"
	"strings"

	fidlcommon "fidl-lsp/third_party/common"

	"fidl-lsp/state"
)

type symbolInfo struct {
	name       string
	definition state.Location
	typeInfo   Type
}

type Type struct {
	// If IsLib is true, other fields are empty.
	// TODO: is there a better way to represent this?
	IsLib bool
	// If IsMethod is true, only Attrs is set.
	IsMethod bool

	// Set if this type is actually a resolved alias
	FromTypeAlias *string
	Attrs         []Attribute

	Kind TypeKind

	Array      *ArrayTypeInfo
	Vector     *VectorTypeInfo
	String     *StringTypeInfo
	Handle     *HandleTypeInfo
	Request    *RequestTypeInfo
	Primitive  *PrimitiveTypeInfo
	Identifier *IdentifierTypeInfo
}

type ArrayTypeInfo struct {
	ElementType  Type
	ElementCount uint
}

type VectorTypeInfo struct {
	ElementType  Type
	ElementCount *uint
	Nullable     bool
}

type StringTypeInfo struct {
	ElementCount *uint
	Nullable     bool
}

type HandleTypeInfo struct {
	Subtype  HandleSubtype
	Rights   uint
	Nullable bool
}

type HandleSubtype string

const (
	Handle       HandleSubtype = "handle"
	Bti                        = "bti"
	Channel                    = "channel"
	Clock                      = "clock"
	DebugLog                   = "debuglog"
	Event                      = "event"
	Eventpair                  = "eventpair"
	Exception                  = "exception"
	Fifo                       = "fifo"
	Guest                      = "guest"
	Interrupt                  = "interrupt"
	Iommu                      = "iommu"
	Job                        = "job"
	Pager                      = "pager"
	PciDevice                  = "pcidevice"
	Pmt                        = "pmt"
	Port                       = "port"
	Process                    = "process"
	Profile                    = "profile"
	Resource                   = "resource"
	Socket                     = "socket"
	Stream                     = "stream"
	SuspendToken               = "suspendtoken"
	Thread                     = "thread"
	Time                       = "timer"
	Vcpu                       = "vcpu"
	Vmar                       = "vmar"
	Vmo                        = "vmo"
)

type RequestTypeInfo struct {
	Subtype  string
	Nullable bool
}

type PrimitiveTypeInfo struct {
	Subtype PrimitiveSubtype
}

type PrimitiveSubtype string

const (
	Bool    PrimitiveSubtype = "bool"
	Int8                     = "int8"
	Int16                    = "int16"
	Int32                    = "int32"
	Int64                    = "int64"
	Uint8                    = "uint8"
	Uint16                   = "uint16"
	Uint32                   = "uint32"
	Uint64                   = "uint64"
	Float32                  = "float32"
	Float64                  = "float64"
)

// IdentifierTypeInfo is not a perfect analog for `identifier-type` from the
// JSON IR, because it serves as the type for both declarations of identifier
// types and values of identifier types.
//
// For example, if you have declared a struct Foo, and a protocol method that
// takes a Foo, IdentifierTypeInfo will hold the same type information for each
// of the following symbols:
//
//     struct Foo {};
//            ~~~
//     protocol P {
//         Method(Foo foo);
//                ~~~ ~~~
//     };
//
// So it is both a kind of "declaration type" as well as an "identifier type".
// Iff `IsDecl` == true, it is a "declaration type"; otherwise, it is an
// "identifier type", and `Identifier` is the name of a declaration type that
// can be looked up in the symbol map.
type IdentifierTypeInfo struct {
	// If IsDecl is true, all the type information is contained in the tagged
	// type info objects -- Kind and one of {Bits, Const, etc.}.
	// If IsDecl is false, Identifier and Nullable are set, and Identifier is
	// a key to the declaration of the identifier type, in the symbolMap.
	IsDecl     bool
	Identifier string
	Nullable   bool

	Kind IdentifierKind
	Name string

	Bits      *BitsTypeInfo
	Const     *ConstTypeInfo
	Enum      *EnumTypeInfo
	TypeAlias *TypeAliasTypeInfo
}

type IdentifierKind string

const (
	BitsKind      IdentifierKind = "bits"
	ConstKind                    = "const"
	EnumKind                     = "enum"
	ProtocolKind                 = "protocol"
	ServiceKind                  = "service"
	StructKind                   = "struct"
	TableKind                    = "table"
	UnionKind                    = "union"
	TypeAliasKind                = "typeAlias"
)

type BitsTypeInfo struct {
	Type Type
}
type ConstTypeInfo struct {
	Type  Type
	Value string
}
type EnumTypeInfo struct {
	Type PrimitiveSubtype
}
type TypeAliasTypeInfo struct {
	Type Type
}

type nameInLibrary struct {
	lib  *Library // Left nil if uncertain
	name fidlcommon.Name
}

func (a *Analyzer) symbolToFullyQualifiedName(fs *state.FileSystem, sym state.Symbol) (nameInLibrary, error) {
	// TODO: if we want to support hovering over members (e.g. struct fields,
	// method parameters, bits members) or protocol methods, we need to check
	// here whether the symbol is namespaced -- whether it is inside a
	// declaration.
	// If it is, prepend it with that declaration's name. For example, this
	// struct field:
	//
	//     struct Foo {
	//         MyType my_field;
	//                ~~~~~~~~
	//     }
	//
	// Would become "library.name/Foo.my_field", as this is how it's stored in
	// the symbol map.

	// If `sym` is a local name (not fully-qualified), we create a FQN by
	// attaching its library name.
	var fqn string
	var lib *Library
	if !strings.Contains(sym.Name, ".") {
		file, err := fs.File(sym.Location.FileID)
		if err != nil {
			return nameInLibrary{}, fmt.Errorf("could not open file `%s`", sym.Location.FileID)
		}
		libName, err := state.LibraryOfFile(file)
		if err != nil {
			return nameInLibrary{}, fmt.Errorf(
				"could not find library of symbol `%s` in file `%s`",
				sym.Name,
				sym.Location.FileID,
			)
		}
		fqn = libName.FullyQualifiedName() + "/" + sym.Name
		// We know this symbol's library, so we can return it
		if library, ok := a.getLibraryWithFile(libName, sym.Location.FileID); ok {
			lib = library
		}
	} else {
		// If the symbol contains '.', we assume it is a fully-qualified name.
		i := strings.LastIndex(sym.Name, ".")
		fqn = sym.Name[:i] + "/" + sym.Name[i+1:]
	}

	// Convert `fqn` to a fidlcommon.Name.
	name, err := fidlcommon.ReadName(fqn)
	if err != nil {
		return nameInLibrary{}, fmt.Errorf("could not read fully-qualified name `%s`: %s", fqn, err)
	}
	return nameInLibrary{lib: lib, name: name}, nil
}

func (a *Analyzer) lookupSymbolInfo(name fidlcommon.Name) (*symbolInfo, error) {
	// We don't call getLibraryWithFile here because we don't know for sure
	// which library this symbol is part of. Unless the library is declared as a
	// dependency of the library that includes this symbol, it couldn't be
	// resolved, and we want to be able to resolve the symbol even if a
	// dependency isn't declared.
	lib, ok := a.getLibrary(name.LibraryName())
	if !ok {
		return nil, fmt.Errorf("unknown library `%s`", name.LibraryName().FullyQualifiedName())
	}
	return a.lookupSymbolInfoInLibrary(name, lib)
}

func (a *Analyzer) lookupSymbolInfoInLibrary(name fidlcommon.Name, lib *Library) (*symbolInfo, error) {
	if lib.ir == nil {
		if err := a.compileLibrary(lib); err != nil {
			return nil, fmt.Errorf(
				"error importing library `%s`: %s",
				name.LibraryName().FullyQualifiedName(),
				err,
			)
		}
	}

	// Check that we have a symbolMap for this library, and look up this
	// symbol's definition location in that symbolMap.
	if lib.symbols == nil {
		return nil, fmt.Errorf(
			"no symbol map for library `%s`",
			name.LibraryName().FullyQualifiedName(),
		)
	}
	symInfo, ok := lib.symbols[name.FullyQualifiedName()]
	if !ok {
		return nil, fmt.Errorf("could not find symbol `%s`", name.FullyQualifiedName())
	}

	return symInfo, nil
}
