// 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"

	"fidl-lsp/third_party/fidlgen"

	"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 fidlgen.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 fidlgen.Name.
	name, err := fidlgen.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 fidlgen.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 fidlgen.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
}
