// Copyright 2019 The Go 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 cache

import (
	"context"
	"go/ast"
	"go/types"

	"golang.org/x/tools/internal/lsp/protocol"
	"golang.org/x/tools/internal/lsp/source"
	"golang.org/x/tools/internal/span"
	errors "golang.org/x/xerrors"
)

// pkg contains the type information needed by the source package.
type pkg struct {
	// ID and package path have their own types to avoid being used interchangeably.
	id      packageID
	pkgPath packagePath
	mode    source.ParseMode

	goFiles         []source.ParseGoHandle
	compiledGoFiles []source.ParseGoHandle
	errors          []*source.Error
	imports         map[packagePath]*pkg
	types           *types.Package
	typesInfo       *types.Info
	typesSizes      types.Sizes
}

// Declare explicit types for package paths and IDs to ensure that we never use
// an ID where a path belongs, and vice versa. If we confused the two, it would
// result in confusing errors because package IDs often look like package paths.
type packageID string
type packagePath string

// Declare explicit types for files and directories to distinguish between the two.
type fileURI span.URI
type directoryURI span.URI

func (p *pkg) ID() string {
	return string(p.id)
}

func (p *pkg) PkgPath() string {
	return string(p.pkgPath)
}

func (p *pkg) CompiledGoFiles() []source.ParseGoHandle {
	return p.compiledGoFiles
}

func (p *pkg) File(uri span.URI) (source.ParseGoHandle, error) {
	for _, ph := range p.compiledGoFiles {
		if ph.File().Identity().URI == uri {
			return ph, nil
		}
	}
	for _, ph := range p.goFiles {
		if ph.File().Identity().URI == uri {
			return ph, nil
		}
	}
	return nil, errors.Errorf("no ParseGoHandle for %s", uri)
}

func (p *pkg) GetSyntax() []*ast.File {
	var syntax []*ast.File
	for _, ph := range p.compiledGoFiles {
		file, _, _, err := ph.Cached()
		if err == nil {
			syntax = append(syntax, file)
		}
	}
	return syntax
}

func (p *pkg) GetErrors() []*source.Error {
	return p.errors
}

func (p *pkg) GetTypes() *types.Package {
	return p.types
}

func (p *pkg) GetTypesInfo() *types.Info {
	return p.typesInfo
}

func (p *pkg) GetTypesSizes() types.Sizes {
	return p.typesSizes
}

func (p *pkg) IsIllTyped() bool {
	return p.types == nil || p.typesInfo == nil || p.typesSizes == nil
}

func (p *pkg) GetImport(pkgPath string) (source.Package, error) {
	if imp := p.imports[packagePath(pkgPath)]; imp != nil {
		return imp, nil
	}
	// Don't return a nil pointer because that still satisfies the interface.
	return nil, errors.Errorf("no imported package for %s", pkgPath)
}

func (p *pkg) Imports() []source.Package {
	var result []source.Package
	for _, imp := range p.imports {
		result = append(result, imp)
	}
	return result
}

func (s *snapshot) FindAnalysisError(ctx context.Context, pkgID, analyzerName, msg string, rng protocol.Range) (*source.Error, error) {
	analyzer, ok := s.View().Options().Analyzers[analyzerName]
	if !ok {
		return nil, errors.Errorf("unexpected analyzer: %s", analyzerName)
	}
	act, err := s.actionHandle(ctx, packageID(pkgID), source.ParseFull, analyzer)
	if err != nil {
		return nil, err
	}
	errs, _, err := act.analyze(ctx)
	if err != nil {
		return nil, err
	}
	for _, err := range errs {
		if err.Category != analyzerName {
			continue
		}
		if err.Message != msg {
			continue
		}
		if protocol.CompareRange(err.Range, rng) != 0 {
			continue
		}
		return err, nil
	}
	return nil, errors.Errorf("no matching diagnostic for %s:%v", pkgID, analyzerName)
}
