// Copyright 2016 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package svctool

import (
	"bytes"
	"context"
	"fmt"
	"go/ast"
	goparser "go/parser"
	"go/printer"
	"go/token"
	"path/filepath"
	"strings"

	"go.chromium.org/luci/common/logging"
)

type fileAndType struct {
	f *ast.File
	t *ast.TypeSpec
}

type parser struct {
	services     []*Service
	extraImports map[string]string

	fileSet *token.FileSet
	files   []*ast.File
	types   []string

	typeCache  map[string]fileAndType
	exprStrBuf bytes.Buffer
}

// parsePackage parses .go files and fills in p.files with the ASTs.
// Files must be in the same directory and have the same package name.
func (p *parser) parsePackage(fileNames []string) error {
	if len(fileNames) == 0 {
		return fmt.Errorf("fileNames is empty")
	}
	for i, name := range fileNames {
		if i > 0 && filepath.Dir(name) != filepath.Dir(fileNames[0]) {
			return fmt.Errorf("Go files belong to different directories")
		}
		if !strings.HasSuffix(name, ".go") {
			continue
		}
		file, err := goparser.ParseFile(p.fileSet, name, nil, 0)
		if err != nil {
			return fmt.Errorf("parsing %s: %s", name, err)
		}
		if len(p.files) > 0 && file.Name.Name != p.files[0].Name.Name {
			return fmt.Errorf("Go files belong to different packages")
		}
		p.files = append(p.files, file)
	}
	if len(p.files) == 0 {
		return fmt.Errorf("no buildable Go files")
	}
	return nil
}

func (p *parser) resolveServices(c context.Context) error {
	for _, t := range p.types {
		svc, err := p.resolveService(c, t)
		if err != nil {
			return err
		}
		p.services = append(p.services, svc)
	}
	return nil
}

// recordImport extracts the package referenced by type expression typ,
// resolves its path and saves to p.extraImports.
func (p *parser) recordImport(f *ast.File, typ ast.Expr) error {
	if star, ok := typ.(*ast.StarExpr); ok {
		typ = star.X
	}

	sel, ok := typ.(*ast.SelectorExpr)
	if !ok {
		return nil
	}
	pkgID, ok := sel.X.(*ast.Ident)
	if !ok {
		return nil
	}

	if _, ok := p.extraImports[pkgID.Name]; ok {
		return nil
	}

	path := ""
	for _, i := range f.Imports {
		if i.Name.Name == pkgID.Name {
			path = strings.Trim(i.Path.Value, `"`)
			break
		}
	}
	if path == "" {
		return fmt.Errorf("could not resolve package %s", pkgID.Name)
	}
	if p.extraImports == nil {
		p.extraImports = make(map[string]string)
	}
	p.extraImports[pkgID.Name] = path
	return nil
}

func (p *parser) resolveService(c context.Context, typeName string) (*Service, error) {
	file, typeSpec := p.findType(typeName)
	if typeSpec == nil {
		return nil, fmt.Errorf("type %s not found", typeName)
	}
	iface, ok := typeSpec.Type.(*ast.InterfaceType)
	if !ok {
		return nil, fmt.Errorf("%s is not an interface", typeName)
	}

	const suffix = "Server"
	if !strings.HasSuffix(typeName, suffix) {
		return nil, fmt.Errorf("expected type name %q to end with %q", typeName, suffix)
	}

	if iface.Methods == nil {
		return nil, fmt.Errorf("interface %q has no methods", typeName)
	}

	svc := &Service{
		TypeName: typeName,
		Node:     iface,
	}
	for _, m := range iface.Methods.List {
		signature, ok := m.Type.(*ast.FuncType)
		if !ok {
			ifaceName, err := p.exprString(m.Type)
			if err != nil {
				return nil, err
			}
			return nil, fmt.Errorf("%s embeds %s; not supported", typeName, ifaceName)
		}

		name := m.Names[0].Name
		if signature.Params == nil {
			logging.Warningf(c, "%s.%s: no params", typeName, name)
			continue
		}
		params := signature.Params.List
		if len(params) != 2 {
			logging.Warningf(
				c,
				"%s.%s: param count is %d; expected 2",
				typeName, name, len(params))
			continue
		}
		if signature.Results == nil {
			logging.Warningf(c, "%s.%s: returns nothing", typeName, name)
			continue
		}
		results := signature.Results.List
		if len(results) != 2 {
			logging.Warningf(
				c,
				"%s.%s: return value count is %d; expected 2",
				typeName, name, len(results))
			continue
		}

		method := &Method{
			Node: m,
			Name: m.Names[0].Name,
		}

		if err := p.recordImport(file, params[1].Type); err != nil {
			return nil, err
		}
		var err error
		method.InputType, err = p.exprString(params[1].Type)
		if err != nil {
			return nil, err
		}

		if err := p.recordImport(file, results[0].Type); err != nil {
			return nil, err
		}
		method.OutputType, err = p.exprString(results[0].Type)
		if err != nil {
			return nil, err
		}
		svc.Methods = append(svc.Methods, method)
	}
	return svc, nil
}

func (p *parser) findType(name string) (*ast.File, *ast.TypeSpec) {
	if p.typeCache == nil {
		p.typeCache = map[string]fileAndType{}
	}
	if pair, ok := p.typeCache[name]; ok {
		return pair.f, pair.t
	}

	for _, f := range p.files {
		for _, decl := range f.Decls {
			gen, ok := decl.(*ast.GenDecl)
			if !ok || gen.Tok != token.TYPE {
				continue
			}
			for _, spec := range gen.Specs {
				typeSpec := spec.(*ast.TypeSpec)
				p.typeCache[typeSpec.Name.Name] = fileAndType{f, typeSpec}
				if typeSpec.Name.Name == name {
					return f, typeSpec
				}
			}
		}
	}

	return nil, nil
}

// exprString renders expr to string.
func (p *parser) exprString(expr ast.Expr) (string, error) {
	p.exprStrBuf.Reset()
	err := printer.Fprint(&p.exprStrBuf, p.fileSet, expr)
	return p.exprStrBuf.String(), err
}
