// Copyright 2020 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 staticdata

import (
	"path"
	"sort"
	"strings"

	"cmd/compile/internal/base"
	"cmd/compile/internal/ir"
	"cmd/compile/internal/objw"
	"cmd/compile/internal/types"
	"cmd/internal/obj"
)

const (
	embedUnknown = iota
	embedBytes
	embedString
	embedFiles
)

func embedFileList(v *ir.Name, kind int) []string {
	// Build list of files to store.
	have := make(map[string]bool)
	var list []string
	for _, e := range *v.Embed {
		for _, pattern := range e.Patterns {
			files, ok := base.Flag.Cfg.Embed.Patterns[pattern]
			if !ok {
				base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
			}
			for _, file := range files {
				if base.Flag.Cfg.Embed.Files[file] == "" {
					base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
					continue
				}
				if !have[file] {
					have[file] = true
					list = append(list, file)
				}
				if kind == embedFiles {
					for dir := path.Dir(file); dir != "." && !have[dir]; dir = path.Dir(dir) {
						have[dir] = true
						list = append(list, dir+"/")
					}
				}
			}
		}
	}
	sort.Slice(list, func(i, j int) bool {
		return embedFileLess(list[i], list[j])
	})

	if kind == embedString || kind == embedBytes {
		if len(list) > 1 {
			base.ErrorfAt(v.Pos(), "invalid go:embed: multiple files for type %v", v.Type())
			return nil
		}
	}

	return list
}

// embedKind determines the kind of embedding variable.
func embedKind(typ *types.Type) int {
	if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
		return embedFiles
	}
	if typ.Kind() == types.TSTRING {
		return embedString
	}
	if typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
		return embedBytes
	}
	return embedUnknown
}

func embedFileNameSplit(name string) (dir, elem string, isDir bool) {
	if name[len(name)-1] == '/' {
		isDir = true
		name = name[:len(name)-1]
	}
	i := len(name) - 1
	for i >= 0 && name[i] != '/' {
		i--
	}
	if i < 0 {
		return ".", name, isDir
	}
	return name[:i], name[i+1:], isDir
}

// embedFileLess implements the sort order for a list of embedded files.
// See the comment inside ../../../../embed/embed.go's Files struct for rationale.
func embedFileLess(x, y string) bool {
	xdir, xelem, _ := embedFileNameSplit(x)
	ydir, yelem, _ := embedFileNameSplit(y)
	return xdir < ydir || xdir == ydir && xelem < yelem
}

// WriteEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS.
func WriteEmbed(v *ir.Name) {
	// TODO(mdempsky): User errors should be reported by the frontend.

	commentPos := (*v.Embed)[0].Pos
	if base.Flag.Cfg.Embed.Patterns == nil {
		base.ErrorfAt(commentPos, "invalid go:embed: build system did not supply embed configuration")
		return
	}
	kind := embedKind(v.Type())
	if kind == embedUnknown {
		base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
		return
	}

	files := embedFileList(v, kind)
	switch kind {
	case embedString, embedBytes:
		file := files[0]
		fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil)
		if err != nil {
			base.ErrorfAt(v.Pos(), "embed %s: %v", file, err)
		}
		sym := v.Linksym()
		off := 0
		off = objw.SymPtr(sym, off, fsym, 0)       // data string
		off = objw.Uintptr(sym, off, uint64(size)) // len
		if kind == embedBytes {
			objw.Uintptr(sym, off, uint64(size)) // cap for slice
		}

	case embedFiles:
		slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`)
		off := 0
		// []files pointed at by Files
		off = objw.SymPtr(slicedata, off, slicedata, 3*types.PtrSize) // []file, pointing just past slice
		off = objw.Uintptr(slicedata, off, uint64(len(files)))
		off = objw.Uintptr(slicedata, off, uint64(len(files)))

		// embed/embed.go type file is:
		//	name string
		//	data string
		//	hash [16]byte
		// Emit one of these per file in the set.
		const hashSize = 16
		hash := make([]byte, hashSize)
		for _, file := range files {
			off = objw.SymPtr(slicedata, off, StringSym(v.Pos(), file), 0) // file string
			off = objw.Uintptr(slicedata, off, uint64(len(file)))
			if strings.HasSuffix(file, "/") {
				// entry for directory - no data
				off = objw.Uintptr(slicedata, off, 0)
				off = objw.Uintptr(slicedata, off, 0)
				off += hashSize
			} else {
				fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash)
				if err != nil {
					base.ErrorfAt(v.Pos(), "embed %s: %v", file, err)
				}
				off = objw.SymPtr(slicedata, off, fsym, 0) // data string
				off = objw.Uintptr(slicedata, off, uint64(size))
				off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash))
			}
		}
		objw.Global(slicedata, int32(off), obj.RODATA|obj.LOCAL)
		sym := v.Linksym()
		objw.SymPtr(sym, 0, slicedata, 0)
	}
}
