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

	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
}

func (a *Analyzer) symbolToFullyQualifiedName(fs *state.FileSystem, sym state.Symbol) (fidlcommon.Name, error) {
	// If `sym` is a local name (not fully-qualified), we create a FQN by
	// attaching its library name.
	var fqn string
	if !strings.Contains(sym.Name, ".") {
		file, err := fs.File(sym.Location.FileID)
		if err != nil {
			return fidlcommon.Name{}, fmt.Errorf("could not open file `%s`", sym.Location.FileID)
		}
		libName, err := state.LibraryOfFile(file)
		if err != nil {
			return fidlcommon.Name{}, fmt.Errorf(
				"could not find library of symbol `%s` in file `%s`",
				sym.Name,
				sym.Location.FileID,
			)
		}
		fqn = libName.FullyQualifiedName() + "/" + sym.Name
	} 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 fidlcommon.Name{}, fmt.Errorf("could not read fully-qualified name `%s`: %s", fqn, err)
	}
	return name, nil
}

func (a *Analyzer) lookupSymbolInfo(name fidlcommon.Name) (*symbolInfo, error) {
	lib, ok := a.libs[name.LibraryName()]
	if !ok {
		return nil, fmt.Errorf("unknown library `%s`", name.LibraryName().FullyQualifiedName())
	}
	if lib.ir == nil {
		if err := a.importLibrary(lib.json); 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
}
