// Copyright 2010 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.

// This file contains the code dealing with package directory trees.

package pkgdoc

import (
	"bytes"
	"go/ast"
	"go/doc"
	"go/parser"
	"go/token"
	"log"
	"path"
	"strings"

	"golang.org/x/website/internal/backport/io/fs"
)

type Dir struct {
	Path     string // directory path
	HasPkg   bool   // true if the directory contains at least one package
	Synopsis string // package documentation, if any
	Dirs     []*Dir // subdirectories
}

func (d *Dir) Name() string {
	return path.Base(d.Path)
}

// DirEntry describes a directory entry.
// The Depth gives the directory depth relative to the overall list,
// for use in presenting a hierarchical directory entry.
type DirEntry struct {
	Depth    int    // >= 0
	Path     string // relative path to directory from listing start
	HasPkg   bool   // true if the directory contains at least one package
	Synopsis string // package documentation, if any
}

func (d *DirEntry) Name() string {
	return path.Base(d.Path)
}

// lookup looks for the *Dir for a given named path, relative to d.
func (d *Dir) lookup(name string) *Dir {
	name = path.Join(d.Path, name)
	if name == d.Path {
		return d
	}
	if d.Path != "." {
		if !strings.HasPrefix(name, d.Path) || name[len(d.Path)] != '/' {
			return nil
		}
		name = name[len(d.Path)+1:]
	}
Walk:
	for i := 0; i <= len(name); i++ {
		if i == len(name) || name[i] == '/' {
			// Find next child along path.
			for _, sub := range d.Dirs {
				if sub.Path == name[:i] {
					d = sub
					continue Walk
				}
			}
			return nil
		}
	}
	return d
}

// list creates a (linear) directory list from a directory tree.
// If filter is set, only the directory entries whose paths match the filter
// are included.
func (d *Dir) list(filter func(string) bool) []DirEntry {
	if d == nil {
		return nil
	}

	root := d
	var list []DirEntry
	root.walk(func(d *Dir, depth int) {
		if depth == 0 || filter != nil && !filter(d.Path) {
			return
		}
		// the path is relative to root.Path - remove the root.Path
		// prefix (the prefix should always be present but avoid
		// crashes and check)
		path := strings.TrimPrefix(d.Path, root.Path)
		// remove leading separator if any - path must be relative
		path = strings.TrimPrefix(path, "/")
		list = append(list, DirEntry{
			Depth:    depth,
			Path:     path,
			HasPkg:   d.HasPkg,
			Synopsis: d.Synopsis,
		})
	})

	if len(list) == 0 {
		return nil
	}
	return list
}

// newDir returns a Dir describing dirpath in fsys.
// When Go files need to be parsed, newDir uses fset.
// If there are no package files and no subdirectories containing packages,
// newDir returns nil.
func newDir(fsys fs.FS, fset *token.FileSet, dirpath string) *Dir {
	var synopses [3]string // prioritized package documentation (0 == highest priority)

	hasPkgFiles := false
	haveSummary := false

	list, err := fs.ReadDir(fsys, dirpath)
	if err != nil {
		// TODO: propagate more. See golang.org/issue/14252.
		log.Printf("newDirTree reading %s: %v", dirpath, err)
	}

	// determine number of subdirectories and if there are package files
	var dirs []*Dir

	for _, de := range list {
		filename := path.Join(dirpath, de.Name())
		switch {
		case isPkgDir(de):
			d := newDir(fsys, fset, filename)
			if d != nil {
				dirs = append(dirs, d)
			}

		case !haveSummary && isPkgFile(de):
			// looks like a package file, but may just be a file ending in ".go";
			// don't just count it yet (otherwise we may end up with hasPkgFiles even
			// though the directory doesn't contain any real package files - was bug)
			// no "optimal" package synopsis yet; continue to collect synopses
			const flags = parser.ParseComments | parser.PackageClauseOnly
			file, err := parseFile(fsys, fset, filename, flags)
			if err != nil {
				log.Printf("parsing %v: %v", filename, err)
				break
			}

			hasPkgFiles = true
			if file.Doc != nil {
				// prioritize documentation
				i := -1
				switch file.Name.Name {
				case path.Base(dirpath):
					i = 0 // normal case: directory name matches package name
				case "main":
					i = 1 // directory contains a main package
				default:
					i = 2 // none of the above
				}
				if 0 <= i && i < len(synopses) && synopses[i] == "" {
					synopses[i] = doc.Synopsis(file.Doc.Text())
				}
			}
			haveSummary = synopses[0] != ""
		}
	}

	// if there are no package files and no subdirectories
	// containing package files, ignore the directory
	if !hasPkgFiles && len(dirs) == 0 {
		return nil
	}

	// select the highest-priority synopsis for the directory entry, if any
	synopsis := ""
	for _, synopsis = range synopses {
		if synopsis != "" {
			break
		}
	}

	return &Dir{
		Path:     dirpath,
		HasPkg:   hasPkgFiles,
		Synopsis: synopsis,
		Dirs:     dirs,
	}
}

func isPkgFile(fi fs.DirEntry) bool {
	name := fi.Name()
	return !fi.IsDir() &&
		path.Ext(name) == ".go" &&
		!strings.HasSuffix(fi.Name(), "_test.go") // ignore test files
}

func isPkgDir(fi fs.DirEntry) bool {
	name := fi.Name()
	return fi.IsDir() &&
		name != "testdata" &&
		len(name) > 0 && name[0] != '_' && name[0] != '.' // ignore _files and .files
}

// walk calls f for each directory in the tree rooted at d, including d itself.
// The depth argument specifies the depth of the directory in the tree.
// The depth of d itself is 0.
func (d *Dir) walk(f func(d *Dir, depth int)) {
	walkDirs(f, d, 0)
}

func walkDirs(f func(d *Dir, depth int), d *Dir, depth int) {
	f(d, depth)
	for _, sub := range d.Dirs {
		walkDirs(f, sub, depth+1)
	}
}

func parseFile(fsys fs.FS, fset *token.FileSet, filename string, mode parser.Mode) (*ast.File, error) {
	src, err := fs.ReadFile(fsys, filename)
	if err != nil {
		return nil, err
	}

	// Temporary ad-hoc fix for issue 5247.
	// TODO(gri,dmitshur) Remove this in favor of a better fix, eventually (see issue 32092).
	replaceLinePrefixCommentsWithBlankLine(src)

	return parser.ParseFile(fset, filename, src, mode)
}

func parseFiles(fsys fs.FS, fset *token.FileSet, dirname string, localnames []string) (map[string]*ast.File, error) {
	files := make(map[string]*ast.File)
	for _, f := range localnames {
		filename := path.Join(dirname, f)
		file, err := parseFile(fsys, fset, filename, parser.ParseComments)
		if err != nil {
			return nil, err
		}
		files[filename] = file
	}

	return files, nil
}

var linePrefix = []byte("//line ")

// This function replaces source lines starting with "//line " with a blank line.
// It does this irrespective of whether the line is truly a line comment or not;
// e.g., the line may be inside a string, or a /*-style comment; however that is
// rather unlikely (proper testing would require a full Go scan which we want to
// avoid for performance).
func replaceLinePrefixCommentsWithBlankLine(src []byte) {
	for {
		i := bytes.Index(src, linePrefix)
		if i < 0 {
			break // we're done
		}
		// 0 <= i && i+len(linePrefix) <= len(src)
		if i == 0 || src[i-1] == '\n' {
			// at beginning of line: blank out line
			for i < len(src) && src[i] != '\n' {
				src[i] = ' '
				i++
			}
		} else {
			// not at beginning of line: skip over prefix
			i += len(linePrefix)
		}
		// i <= len(src)
		src = src[i:]
	}
}
