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

	"fidl-lsp/third_party/fidlgen"

	"fidl-lsp/state"
)

// TypeOfSymbol returns the type information of `sym`.
//
// analysis.Type contains all the information needed to create a human-readable
// description of the type.
func (a *Analyzer) TypeOfSymbol(fs *state.FileSystem, sym state.Symbol) (Type, error) {
	// If `sym` is a library name, return a `library`-kinded TypeInfo.
	libName, err := fidlgen.ReadLibraryName(sym.Name)
	if err == nil {
		// TODO: We could use getLibraryWithFile here, but it would be more
		// complicated: if this library name is a declaration, we should pass it
		// the file the symbol is in; but if it's a library import, we should
		// pass it a file of that imported library.
		if _, isLib := a.getLibrary(libName); isLib {
			return Type{
				IsLib: true,
			}, nil
		}
	}

	// Otherwise, we assume it is a local or fully-qualified name
	name, err := a.symbolToFullyQualifiedName(fs, sym)
	if err != nil {
		return Type{}, fmt.Errorf(
			"could not convert symbol `%s` to fully-qualified name: %s",
			sym.Name,
			err,
		)
	}

	var symInfo *symbolInfo
	if name.lib != nil {
		symInfo, err = a.lookupSymbolInfoInLibrary(name.name, name.lib)
		if err != nil {
			return Type{}, fmt.Errorf(
				"could not find type of symbol `%s`: %s",
				name.name.FullyQualifiedName(),
				err,
			)
		}
	} else {
		symInfo, err = a.lookupSymbolInfo(name.name)
		if err != nil {
			return Type{}, fmt.Errorf(
				"could not find type of symbol `%s`: %s",
				name.name.FullyQualifiedName(),
				err,
			)
		}
	}

	// Resolve identifier type, if necessary.
	if symInfo.typeInfo.Kind == IdentifierType && !symInfo.typeInfo.Identifier.IsDecl {
		// This means that rather than being a declaration, symInfo is a value
		// of an identifier type, so we lookup that type's info based on the
		// type name.
		typeName, err := fidlgen.ReadName(symInfo.typeInfo.Identifier.Identifier)
		if err != nil {
			return Type{}, fmt.Errorf(
				"invalid identifier type `%s`: %s",
				symInfo.typeInfo.Identifier.Identifier,
				err,
			)
		}
		t, err := a.lookupSymbolInfo(typeName)
		if err != nil {
			return Type{}, fmt.Errorf(
				"could not find identifier type `%s` of symbol `%s`: %s",
				typeName.FullyQualifiedName(),
				name.name.FullyQualifiedName(),
				err,
			)
		}
		identifierType := t.typeInfo
		identifierType.Identifier.IsDecl = false
		identifierType.Identifier.Nullable = symInfo.typeInfo.Identifier.Nullable
		identifierType.Identifier.Identifier = symInfo.typeInfo.Identifier.Identifier
		return identifierType, nil
	}

	// Resolve aliased identifier type, if necessary.
	if symInfo.typeInfo.Kind == IdentifierType &&
		symInfo.typeInfo.Identifier.Kind == TypeAliasKind &&
		symInfo.typeInfo.Identifier.TypeAlias.Type.Kind == IdentifierType {
		// This means that `sym` is a type alias to an identifier type, so we
		// need to lookup that identifier type's info based on the type name.
		aliasedType := symInfo.typeInfo.Identifier.TypeAlias.Type
		typeName, err := fidlgen.ReadName(aliasedType.Identifier.Identifier)
		if err != nil {
			return Type{}, fmt.Errorf(
				"invalid identifier type `%s`: %s",
				aliasedType.Identifier.Identifier,
				err,
			)
		}
		t, err := a.lookupSymbolInfo(typeName)
		if err != nil {
			return Type{}, fmt.Errorf(
				"could not find identifier type `%s` of symbol `%s`: %s",
				typeName.FullyQualifiedName(),
				name.name.FullyQualifiedName(),
				err,
			)
		}
		identifierType := t.typeInfo
		identifierType.Identifier.Nullable = aliasedType.Identifier.Nullable
		identifierType.Identifier.Identifier = aliasedType.Identifier.Identifier
		symInfo.typeInfo.Identifier.TypeAlias.Type = identifierType
	}

	return symInfo.typeInfo, nil
}
