// Copyright (C) 2014 The Android Open Source Project
//
// 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 generate has support for generating encode and decode methods
// for the binary package automatically.
package generate

import (
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"path/filepath"
	"regexp"
	"strings"

	"android.googlesource.com/platform/tools/gpu/binary/schema"

	"golang.org/x/tools/go/exact"
	"golang.org/x/tools/go/gcimporter"
	"golang.org/x/tools/go/types"
)

// Source holds a file a filename content pair as consumed by go/parser.ParseFile.
type Source struct {
	Filename   string            // The filename for this source
	Content    interface{}       // The content of this source, see ParseFiles for details.
	AST        *ast.File         // The parsed syntax tree
	Directives map[string]string // the set of comment overrides
}

// Module represents a resolvable module. Under normal go layout conditions a
// directory has one module that represents the files that are considered
// when the directory is imported, and a second one that also includes the test
// files. They must be considered separately because otherwise you can get
// import cycles.
type Module struct {
	Sources   []Source       // The set of sources to parse
	Files     []*ast.File    // The parsed files included
	Types     *types.Package // The resolved type information
	Output    *File          // The prepared structures to generate for
	processed bool
}

type Directory struct {
	Name       string // The package name (as used in package declarations)
	ImportPath string // The full import path (as used in import statements)
	Dir        string // The actual directory in which the files live
	Scan       bool   // Whether to scan this directory for structs
	Module     Module // The main module data for this directory
	Test       Module // The test module data for this directory
	loaded     bool
}

type Loader struct {
	Path        string                // The base path of file scanning
	ForceSource bool                  // If true, forces source only imports
	Directories map[string]*Directory // The set of directories considered
	FileSet     *token.FileSet        // The parser file set
	context     build.Context
	config      types.Config
}

// NewLoader creates a new go source loader.
func NewLoader(path string, forceSource bool) *Loader {
	l := &Loader{
		Path:        path,
		ForceSource: forceSource,
		Directories: map[string]*Directory{},
		FileSet:     token.NewFileSet(),
		context:     build.Default,
		config: types.Config{
			IgnoreFuncBodies: true,
			Error:            func(error) {},
			Packages:         map[string]*types.Package{},
		},
	}
	l.config.Import = l.importer
	return l
}

// GetDir returns the Directory that matches the supplied import path.
// It will add a new one if needed.
func (l *Loader) GetDir(importPath string) *Directory {
	dir, ok := l.Directories[importPath]
	if !ok {
		dir = &Directory{
			ImportPath: importPath,
		}
		l.Directories[importPath] = dir
	}
	return dir
}

// ScanFile adds a fake package with the file as it's only source.
func (l *Loader) ScanFile(filename, source string) {
	dir := l.GetDir(filename)
	dir.Scan = true
	dir.loaded = true
	dir.Module.Sources = append(dir.Module.Sources, Source{Filename: filename, Content: source})
}

// ScanPackage marks the directory specified by the import path as needing to be
// scanned for binary structures.
func (l *Loader) ScanPackage(importPath string) {
	l.GetDir(importPath).Scan = true
}

// Process generates output data for all packages that have been marked as
// needing to be scanned.
func (l *Loader) Process() error {
	dirs := make([]*Directory, 0, len(l.Directories))
	for _, dir := range l.Directories {
		if dir.Scan {
			dirs = append(dirs, dir)
		}
	}
	for _, dir := range dirs {
		if err := l.process(dir); err != nil {
			return err
		}
	}
	return nil
}

func (l *Loader) process(dir *Directory) error {
	if !dir.Scan && !dir.Module.processed && !l.ForceSource {
		t, err := gcimporter.Import(l.config.Packages, dir.ImportPath)
		if err == nil {
			dir.Module.processed = true
			dir.Module.Types = t
		}
	}
	if !dir.loaded {
		l.load(dir)
	}
	if !dir.Module.processed {
		dir.Module.processed = true
		if err := l.parse(&dir.Module); err != nil {
			return err
		}
		if err := l.typeCheck(dir, &dir.Module); err != nil {
			return err
		}
		l.config.Packages[dir.ImportPath] = dir.Module.Types
		l.scan(dir, &dir.Module, false)
	}
	if dir.Scan && !dir.Test.processed && len(dir.Test.Sources) > 0 {
		dir.Test.processed = true
		dir.Test.Files = dir.Module.Files
		if err := l.parse(&dir.Test); err != nil {
			return err
		}
		if err := l.typeCheck(dir, &dir.Test); err != nil {
			return err
		}
		l.scan(dir, &dir.Test, true)
	}
	return nil
}

func (l *Loader) load(dir *Directory) {
	dir.loaded = true
	imp, err := l.context.Import(dir.ImportPath, l.Path, 0)
	if err != nil {
		return
	}
	dir.Name = imp.Name
	dir.ImportPath = imp.ImportPath
	dir.Dir = imp.Dir
	for _, filename := range imp.GoFiles {
		dir.Module.Sources = append(dir.Module.Sources, Source{Filename: filepath.Join(dir.Dir, filename)})
	}
	if dir.Scan {
		for _, filename := range imp.TestGoFiles {
			dir.Test.Sources = append(dir.Test.Sources, Source{Filename: filepath.Join(dir.Dir, filename)})
		}
	}
}

var directive = regexp.MustCompile(`binary: *([^= ]+) *(= *(.+))? *`)

func (l *Loader) parse(module *Module) error {
	for i := range module.Sources {
		src := &module.Sources[i]
		file, err := parser.ParseFile(l.FileSet, src.Filename, src.Content, parser.ParseComments)
		if err != nil {
			return err
		}
		src.AST = file
		module.Files = append(module.Files, file)
		src.Directives = make(map[string]string)
		for _, group := range file.Comments {
			for _, comment := range group.List {
				if matches := directive.FindStringSubmatch(comment.Text); len(matches) >= 1 {
					k := matches[1]
					v := matches[3]
					if matches[2] == "" {
						v = "true"
					}
					src.Directives[k] = v
				}
			}
		}
	}
	return nil
}

func (l *Loader) typeCheck(dir *Directory, module *Module) error {
	t, err := l.config.Check(dir.ImportPath, l.FileSet, module.Files, nil)
	module.Types = t
	return err
}

func (l *Loader) scan(dir *Directory, module *Module, isTest bool) error {
	module.Output = &File{
		Package:    dir.Name,
		Path:       dir.Dir,
		Import:     dir.ImportPath,
		Imports:    make(map[string]struct{}),
		Directives: make(map[string]string),
		IsTest:     isTest,
	}
	scope := module.Types.Scope()
	for _, name := range scope.Names() {
		obj := scope.Lookup(name)
		f := l.FileSet.File(obj.Pos())
		filename := f.Name()
		var source *Source
		for i := range module.Sources {
			if module.Sources[i].Filename == filename {
				source = &module.Sources[i]
				break
			}
		}
		if source == nil {
			continue
		}
		if n, ok := obj.(*types.TypeName); ok {
			if t, ok := n.Type().(*types.Named); ok {
				if _, ok := t.Underlying().(*types.Struct); ok {
					if s := FromTypename(module.Types, n, module.Output.Imports); s != nil {
						module.Output.Structs = append(module.Output.Structs, s)
					}
				}
			}
		}
		if c, ok := obj.(*types.Const); ok && c.Exported() {
			if t, ok := c.Type().(*types.Named); ok {
				if t.Obj().Pkg() == obj.Pkg() {
					if _, ok := c.Type().Underlying().(*types.Basic); ok {
						l.addConst(module, source, c)
					}
				}
			}
		}
	}
	for _, s := range module.Sources {
		for k, v := range s.Directives {
			module.Output.Directives[k] = v
		}
	}
	return nil
}

func (l *Loader) addConst(module *Module, source *Source, c *types.Const) {
	t := fromType(module.Types, c.Type(), "", module.Output.Imports)
	name := c.Name()
	directive := fmt.Sprintf("%s#%s", t, name)
	if d, found := source.Directives[directive]; found {
		name = d
	} else {
		name = strings.TrimPrefix(name, t.String())
		name = strings.Trim(name, "_")
	}
	if p, ok := t.(*schema.Primitive); ok {
		switch p.Method {
		case schema.Int8:
			v, _ := exact.Int64Val(c.Val())
			schema.Int8Constant{
				Name:  name,
				Value: int8(v),
			}.Add(&module.Output.Constants, t)
		case schema.Uint8:
			v, _ := exact.Uint64Val(c.Val())
			schema.Uint8Constant{
				Name:  name,
				Value: uint8(v),
			}.Add(&module.Output.Constants, t)
		case schema.Int16:
			v, _ := exact.Int64Val(c.Val())
			schema.Int16Constant{
				Name:  name,
				Value: int16(v),
			}.Add(&module.Output.Constants, t)
		case schema.Uint16:
			v, _ := exact.Uint64Val(c.Val())
			schema.Uint16Constant{
				Name:  name,
				Value: uint16(v),
			}.Add(&module.Output.Constants, t)
		case schema.Int32:
			v, _ := exact.Int64Val(c.Val())
			schema.Int32Constant{
				Name:  name,
				Value: int32(v),
			}.Add(&module.Output.Constants, t)
		case schema.Uint32:
			v, _ := exact.Uint64Val(c.Val())
			schema.Uint32Constant{
				Name:  name,
				Value: uint32(v),
			}.Add(&module.Output.Constants, t)
		case schema.Int64:
			v, _ := exact.Int64Val(c.Val())
			schema.Int64Constant{
				Name:  name,
				Value: v,
			}.Add(&module.Output.Constants, t)
		case schema.Uint64:
			v, _ := exact.Uint64Val(c.Val())
			schema.Uint64Constant{
				Name:  name,
				Value: v,
			}.Add(&module.Output.Constants, t)
		}
	}
}

func (l *Loader) importer(pkgs map[string]*types.Package, importPath string) (*types.Package, error) {
	if importPath == "unsafe" {
		pkgs[importPath] = types.Unsafe
		return types.Unsafe, nil
	}
	dir := l.GetDir(importPath)
	if err := l.process(dir); err != nil {
		return nil, err
	}
	if dir.Module.Types == nil {
		return nil, fmt.Errorf("Cyclic import on %s", dir.ImportPath)
	}
	pkgs[importPath] = dir.Module.Types
	return dir.Module.Types, nil
}
