/* Copyright 2017 The Bazel Authors. All rights reserved.

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 golang

import (
	"fmt"
	"log"
	"path"
	"sort"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/internal/config"
	"github.com/bazelbuild/bazel-gazelle/internal/language/proto"
	"github.com/bazelbuild/bazel-gazelle/internal/rule"
)

// goPackage contains metadata for a set of .go and .proto files that can be
// used to generate Go rules.
type goPackage struct {
	name, dir, rel        string
	library, binary, test goTarget
	proto                 protoTarget
	hasTestdata           bool
	importPath            string
}

// goTarget contains information used to generate an individual Go rule
// (library, binary, or test).
type goTarget struct {
	sources, imports, copts, clinkopts platformStringsBuilder
	cgo                                bool
}

// protoTarget contains information used to generate a go_proto_library rule.
type protoTarget struct {
	name        string
	sources     platformStringsBuilder
	imports     platformStringsBuilder
	hasServices bool
}

// platformStringsBuilder is used to construct rule.PlatformStrings. Bazel
// has some requirements for deps list (a dependency cannot appear in more
// than one select expression; dependencies cannot be duplicated), so we need
// to build these carefully.
type platformStringsBuilder struct {
	strs map[string]platformStringInfo
}

// platformStringInfo contains information about a single string (source,
// import, or option).
type platformStringInfo struct {
	set       platformStringSet
	oss       map[string]bool
	archs     map[string]bool
	platforms map[rule.Platform]bool
}

type platformStringSet int

const (
	genericSet platformStringSet = iota
	osSet
	archSet
	platformSet
)

// addFile adds the file described by "info" to a target in the package "p" if
// the file is buildable.
//
// "cgo" tells whether any ".go" file in the package contains cgo code. This
// affects whether C files are added to targets.
//
// An error is returned if a file is buildable but invalid (for example, a
// test .go file containing cgo code). Files that are not buildable will not
// be added to any target (for example, .txt files).
func (pkg *goPackage) addFile(c *config.Config, info fileInfo, cgo bool) error {
	switch {
	case info.ext == unknownExt || !cgo && (info.ext == cExt || info.ext == csExt):
		return nil
	case info.ext == protoExt:
		if proto.GetProtoConfig(c).Mode == proto.LegacyMode {
			// Only add files in legacy mode. This is used to generate a filegroup
			// that contains all protos. In order modes, we get the .proto files
			// from information emitted by the proto language extension.
			pkg.proto.addFile(c, info)
		}
	case info.isTest:
		if info.isCgo {
			return fmt.Errorf("%s: use of cgo in test not supported", info.path)
		}
		pkg.test.addFile(c, info)
	default:
		pkg.library.addFile(c, info)
	}

	return nil
}

// isCommand returns true if the package name is "main".
func (pkg *goPackage) isCommand() bool {
	return pkg.name == "main"
}

// isBuildable returns true if anything in the package is buildable.
// This is true if the package has Go code that satisfies build constraints
// on any platform or has proto files not in legacy mode.
func (pkg *goPackage) isBuildable(c *config.Config) bool {
	return pkg.firstGoFile() != "" || !pkg.proto.sources.isEmpty()
}

// firstGoFile returns the name of a .go file if the package contains at least
// one .go file, or "" otherwise.
func (pkg *goPackage) firstGoFile() string {
	goSrcs := []platformStringsBuilder{
		pkg.library.sources,
		pkg.binary.sources,
		pkg.test.sources,
	}
	for _, sb := range goSrcs {
		if sb.strs != nil {
			for s := range sb.strs {
				if strings.HasSuffix(s, ".go") {
					return s
				}
			}
		}
	}
	return ""
}

func (pkg *goPackage) haveCgo() bool {
	return pkg.library.cgo || pkg.binary.cgo || pkg.test.cgo
}

func (pkg *goPackage) inferImportPath(c *config.Config) error {
	if pkg.importPath != "" {
		log.Panic("importPath already set")
	}
	gc := getGoConfig(c)
	if !gc.prefixSet {
		return fmt.Errorf("%s: go prefix is not set, so importpath can't be determined for rules. Set a prefix with a '# gazelle:prefix' comment or with -go_prefix on the command line", pkg.dir)
	}
	pkg.importPath = inferImportPath(gc, pkg.rel)

	if pkg.rel == gc.prefixRel {
		pkg.importPath = gc.prefix
	} else {
		fromPrefixRel := strings.TrimPrefix(pkg.rel, gc.prefixRel+"/")
		pkg.importPath = path.Join(gc.prefix, fromPrefixRel)
	}
	return nil
}

func inferImportPath(gc *goConfig, rel string) string {
	if rel == gc.prefixRel {
		return gc.prefix
	} else {
		fromPrefixRel := strings.TrimPrefix(rel, gc.prefixRel+"/")
		return path.Join(gc.prefix, fromPrefixRel)
	}
}

func goProtoPackageName(pkg proto.Package) string {
	if value, ok := pkg.Options["go_package"]; ok {
		if strings.LastIndexByte(value, '/') == -1 {
			return value
		} else {
			if i := strings.LastIndexByte(value, ';'); i != -1 {
				return value[i+1:]
			} else {
				return path.Base(value)
			}
		}
	}
	return strings.Replace(pkg.Name, ".", "_", -1)
}

func goProtoImportPath(gc *goConfig, pkg proto.Package, rel string) string {
	if value, ok := pkg.Options["go_package"]; ok {
		if strings.LastIndexByte(value, '/') == -1 {
			return inferImportPath(gc, rel)
		} else if i := strings.LastIndexByte(value, ';'); i != -1 {
			return value[:i]
		} else {
			return value
		}
	}
	return inferImportPath(gc, rel)
}

func (t *goTarget) addFile(c *config.Config, info fileInfo) {
	t.cgo = t.cgo || info.isCgo
	add := getPlatformStringsAddFunction(c, info, nil)
	add(&t.sources, info.name)
	add(&t.imports, info.imports...)
	for _, copts := range info.copts {
		optAdd := add
		if len(copts.tags) > 0 {
			optAdd = getPlatformStringsAddFunction(c, info, copts.tags)
		}
		optAdd(&t.copts, copts.opts)
	}
	for _, clinkopts := range info.clinkopts {
		optAdd := add
		if len(clinkopts.tags) > 0 {
			optAdd = getPlatformStringsAddFunction(c, info, clinkopts.tags)
		}
		optAdd(&t.clinkopts, clinkopts.opts)
	}
}

func protoTargetFromProtoPackage(name string, pkg proto.Package) protoTarget {
	target := protoTarget{name: name}
	for f := range pkg.Files {
		target.sources.addGenericString(f)
	}
	for i := range pkg.Imports {
		target.imports.addGenericString(i)
	}
	target.hasServices = pkg.HasServices
	return target
}

func (t *protoTarget) addFile(c *config.Config, info fileInfo) {
	t.sources.addGenericString(info.name)
	for _, imp := range info.imports {
		t.imports.addGenericString(imp)
	}
	t.hasServices = t.hasServices || info.hasServices
}

// getPlatformStringsAddFunction returns a function used to add strings to
// a *platformStringsBuilder under the same set of constraints. This is a
// performance optimization to avoid evaluating constraints repeatedly.
func getPlatformStringsAddFunction(c *config.Config, info fileInfo, cgoTags tagLine) func(sb *platformStringsBuilder, ss ...string) {
	isOSSpecific, isArchSpecific := isOSArchSpecific(info, cgoTags)

	switch {
	case !isOSSpecific && !isArchSpecific:
		if checkConstraints(c, "", "", info.goos, info.goarch, info.tags, cgoTags) {
			return func(sb *platformStringsBuilder, ss ...string) {
				for _, s := range ss {
					sb.addGenericString(s)
				}
			}
		}

	case isOSSpecific && !isArchSpecific:
		var osMatch []string
		for _, os := range rule.KnownOSs {
			if checkConstraints(c, os, "", info.goos, info.goarch, info.tags, cgoTags) {
				osMatch = append(osMatch, os)
			}
		}
		if len(osMatch) > 0 {
			return func(sb *platformStringsBuilder, ss ...string) {
				for _, s := range ss {
					sb.addOSString(s, osMatch)
				}
			}
		}

	case !isOSSpecific && isArchSpecific:
		var archMatch []string
		for _, arch := range rule.KnownArchs {
			if checkConstraints(c, "", arch, info.goos, info.goarch, info.tags, cgoTags) {
				archMatch = append(archMatch, arch)
			}
		}
		if len(archMatch) > 0 {
			return func(sb *platformStringsBuilder, ss ...string) {
				for _, s := range ss {
					sb.addArchString(s, archMatch)
				}
			}
		}

	default:
		var platformMatch []rule.Platform
		for _, platform := range rule.KnownPlatforms {
			if checkConstraints(c, platform.OS, platform.Arch, info.goos, info.goarch, info.tags, cgoTags) {
				platformMatch = append(platformMatch, platform)
			}
		}
		if len(platformMatch) > 0 {
			return func(sb *platformStringsBuilder, ss ...string) {
				for _, s := range ss {
					sb.addPlatformString(s, platformMatch)
				}
			}
		}
	}

	return func(_ *platformStringsBuilder, _ ...string) {}
}

func (sb *platformStringsBuilder) isEmpty() bool {
	return sb.strs == nil
}

func (sb *platformStringsBuilder) hasGo() bool {
	for s := range sb.strs {
		if strings.HasSuffix(s, ".go") {
			return true
		}
	}
	return false
}

func (sb *platformStringsBuilder) addGenericString(s string) {
	if sb.strs == nil {
		sb.strs = make(map[string]platformStringInfo)
	}
	sb.strs[s] = platformStringInfo{set: genericSet}
}

func (sb *platformStringsBuilder) addOSString(s string, oss []string) {
	if sb.strs == nil {
		sb.strs = make(map[string]platformStringInfo)
	}
	si, ok := sb.strs[s]
	if !ok {
		si.set = osSet
		si.oss = make(map[string]bool)
	}
	switch si.set {
	case genericSet:
		return
	case osSet:
		for _, os := range oss {
			si.oss[os] = true
		}
	default:
		si.convertToPlatforms()
		for _, os := range oss {
			for _, arch := range rule.KnownOSArchs[os] {
				si.platforms[rule.Platform{OS: os, Arch: arch}] = true
			}
		}
	}
	sb.strs[s] = si
}

func (sb *platformStringsBuilder) addArchString(s string, archs []string) {
	if sb.strs == nil {
		sb.strs = make(map[string]platformStringInfo)
	}
	si, ok := sb.strs[s]
	if !ok {
		si.set = archSet
		si.archs = make(map[string]bool)
	}
	switch si.set {
	case genericSet:
		return
	case archSet:
		for _, arch := range archs {
			si.archs[arch] = true
		}
	default:
		si.convertToPlatforms()
		for _, arch := range archs {
			for _, os := range rule.KnownArchOSs[arch] {
				si.platforms[rule.Platform{OS: os, Arch: arch}] = true
			}
		}
	}
	sb.strs[s] = si
}

func (sb *platformStringsBuilder) addPlatformString(s string, platforms []rule.Platform) {
	if sb.strs == nil {
		sb.strs = make(map[string]platformStringInfo)
	}
	si, ok := sb.strs[s]
	if !ok {
		si.set = platformSet
		si.platforms = make(map[rule.Platform]bool)
	}
	switch si.set {
	case genericSet:
		return
	default:
		si.convertToPlatforms()
		for _, p := range platforms {
			si.platforms[p] = true
		}
	}
	sb.strs[s] = si
}

func (sb *platformStringsBuilder) build() rule.PlatformStrings {
	var ps rule.PlatformStrings
	for s, si := range sb.strs {
		switch si.set {
		case genericSet:
			ps.Generic = append(ps.Generic, s)
		case osSet:
			if ps.OS == nil {
				ps.OS = make(map[string][]string)
			}
			for os := range si.oss {
				ps.OS[os] = append(ps.OS[os], s)
			}
		case archSet:
			if ps.Arch == nil {
				ps.Arch = make(map[string][]string)
			}
			for arch := range si.archs {
				ps.Arch[arch] = append(ps.Arch[arch], s)
			}
		case platformSet:
			if ps.Platform == nil {
				ps.Platform = make(map[rule.Platform][]string)
			}
			for p := range si.platforms {
				ps.Platform[p] = append(ps.Platform[p], s)
			}
		}
	}
	sort.Strings(ps.Generic)
	if ps.OS != nil {
		for _, ss := range ps.OS {
			sort.Strings(ss)
		}
	}
	if ps.Arch != nil {
		for _, ss := range ps.Arch {
			sort.Strings(ss)
		}
	}
	if ps.Platform != nil {
		for _, ss := range ps.Platform {
			sort.Strings(ss)
		}
	}
	return ps
}

func (sb *platformStringsBuilder) buildFlat() []string {
	strs := make([]string, 0, len(sb.strs))
	for s := range sb.strs {
		strs = append(strs, s)
	}
	sort.Strings(strs)
	return strs
}

func (si *platformStringInfo) convertToPlatforms() {
	switch si.set {
	case genericSet:
		log.Panic("cannot convert generic string to platforms")
	case platformSet:
		return
	case osSet:
		si.set = platformSet
		si.platforms = make(map[rule.Platform]bool)
		for os := range si.oss {
			for _, arch := range rule.KnownOSArchs[os] {
				si.platforms[rule.Platform{OS: os, Arch: arch}] = true
			}
		}
		si.oss = nil
	case archSet:
		si.set = platformSet
		si.platforms = make(map[rule.Platform]bool)
		for arch := range si.archs {
			for _, os := range rule.KnownArchOSs[arch] {
				si.platforms[rule.Platform{OS: os, Arch: arch}] = true
			}
		}
		si.archs = nil
	}
}
