package bazel

import (
	"encoding/json"
	"strings"

	"github.com/go-python/gpython/ast"
	"github.com/go-python/gpython/parser"
	"go.skia.org/infra/go/skerr"
)

// IsBazelFile returns true if the filename looks like a Bazel file.
func IsBazelFile(file string) bool {
	return strings.HasSuffix(file, "WORKSPACE") ||
		strings.HasSuffix(file, ".bazel") ||
		strings.HasSuffix(file, ".bzl")
}

// DependencyID represents the unique identifier for a dependency.
type DependencyID string

// Dependency represents one dependency version pin.
type Dependency struct {
	ID         DependencyID
	Version    string
	versionPos *ast.Pos
	SHA256     string
	sha256Pos  *ast.Pos
}

// Validate returns an error if the Dependency is not valid.
func (d Dependency) Validate() error {
	if d.ID == "" {
		return skerr.Fmt("ID is unset")
	}
	if d.Version == "" {
		return skerr.Fmt("Version is unset")
	}
	if d.versionPos == nil {
		return skerr.Fmt("versionPos is unset")
	}
	if d.SHA256 == "" {
		return skerr.Fmt("SHA256 is unset")
	}
	if d.sha256Pos == nil {
		return skerr.Fmt("sha256Pos is unset")
	}
	return nil
}

// GetDep parses the file contents and returns the given dependency.
func GetDep(content string, dep DependencyID) (Dependency, error) {
	entries, err := ParseDeps(content)
	if err != nil {
		return Dependency{}, skerr.Wrap(err)
	}
	entry, ok := entries[dep]
	if !ok {
		b, err := json.MarshalIndent(entries, "", "  ")
		if err == nil {
			return Dependency{}, skerr.Fmt("Cannot find item with id=%q from these entries:\n%s", dep, string(b))
		} else {
			return Dependency{}, skerr.Fmt("Unable to find %q! Failed to encode entries with: %s", dep, err)
		}
	}
	return entry, nil
}

// SetDep parses the file contents, updates the version of the given
// dependency, and returns the new file contents or any error that occurred.
func SetDep(content string, id DependencyID, version, sha256 string) (string, error) {
	if version == "" || sha256 == "" {
		return "", skerr.Fmt("version and sha256 are required")
	}

	// Parse the file content.
	entries, err := ParseDeps(content)
	if err != nil {
		return "", skerr.Wrap(err)
	}

	// Find the requested dependency.
	dep, ok := entries[id]
	if !ok {
		return "", skerr.Fmt("Failed to find dependency with id %q", id)
	}

	// Replace the old version with the new.
	lines := strings.Split(content, "\n")
	updateDep(lines, dep.versionPos, dep.Version, version)
	updateDep(lines, dep.sha256Pos, dep.SHA256, sha256)
	return strings.Join(lines, "\n"), nil
}

// updateDep updates a dependency version in the given file content lines.
func updateDep(contentLines []string, pos *ast.Pos, old, new string) {
	lineIdx := pos.Lineno - 1 // Lineno starts at 1.
	line := contentLines[lineIdx]
	newLine := line[:pos.ColOffset] + strings.Replace(line[pos.ColOffset:], old, new, 1)
	contentLines[lineIdx] = newLine
}

// ParseDeps parses the file contents and returns all dependencies, keyed by ID.
func ParseDeps(content string) (map[DependencyID]Dependency, error) {
	parsed, err := parser.ParseString(content, "exec")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	// Loop through all top-level statements in the file, collecting
	// dependencies and the positions in the file where their versions are set.
	deps := map[DependencyID]Dependency{}
	for _, stmt := range parsed.(*ast.Module).Body {
		// The dependencies we're looking for are function calls, each of which
		// lives inside an ExprStmt. We ignore all other types of Stmt.
		//
		// For example:
		//
		// # This is a top-level expression statement, which is a function call:
		// container_pull(
		//     name = "empty_container",
		//     digest = "sha256:1e014f84205d569a5cc3be4e108ca614055f7e21d11928946113ab3f36054801",
		//     registry = "index.docker.io",
		//     repository = "alpine",
		// )
		//
		// # This is a top-level assignment statement. It will be ignored:
		// PROTOC_BUILD_FILE_CONTENT = """
		// exports_files(["bin/protoc"], visibility = ["//visibility:public"])
		// """
		if stmt.Type().Name == ast.ExprStmtType.Name {
			exprStmt := stmt.(*ast.ExprStmt).Value
			if exprStmt.Type().Name == ast.CallType.Name {
				dep, foundDep, err := parseCall(exprStmt.(*ast.Call))
				if err != nil {
					return nil, skerr.Wrap(err)
				}
				if foundDep {
					if err := dep.Validate(); err != nil {
						return nil, skerr.Wrap(err)
					}
					if _, ok := deps[dep.ID]; ok {
						return nil, skerr.Fmt("found multiple entries for %q", dep.ID)
					}
					deps[dep.ID] = dep
				}
			}
		}
	}
	return deps, nil
}

// parseCall parses a Call to return a dependency and the position where its
// version is defined, if a dependency can be found. The boolean return value
// indicates whether a dependency was found.
func parseCall(call *ast.Call) (Dependency, bool, error) {
	funcName := string(call.Func.(*ast.Name).Id)
	parseFn := map[string]func(*ast.Call) (Dependency, error){
		"cipd_install":   parseDepFromCallFunc("cipd_package", "tag"),
		"container_pull": parseContainerPull,
	}[funcName]
	if parseFn != nil {
		dep, err := parseFn(call)
		if err != nil {
			return Dependency{}, false, skerr.Wrapf(err, "parsing %q call at line %d", funcName, call.Func.(*ast.Name).Lineno)
		}
		return dep, true, nil
	}
	return Dependency{}, false, nil
}

// parseDepFromCall is a helper function used to extract a dependency from a
// Call using the given idKeyword and versionKeyword.
func parseDepFromCallFunc(idKeyword, versionKeyword string) func(*ast.Call) (Dependency, error) {
	return func(call *ast.Call) (Dependency, error) {
		id, _, err := getCallArgValueString(call, idKeyword)
		if err != nil {
			return Dependency{}, skerr.Wrap(err)
		}
		version, versionPos, err := getCallArgValueString(call, versionKeyword)
		if err != nil {
			return Dependency{}, skerr.Wrap(err)
		}
		sha256, sha256Pos, err := getCallArgValueString(call, "sha256")
		if err != nil {
			return Dependency{}, skerr.Wrap(err)
		}
		return Dependency{
			ID:         DependencyID(id),
			Version:    version,
			versionPos: versionPos,
			SHA256:     sha256,
			sha256Pos:  sha256Pos,
		}, nil
	}
}

// parseContainerPull parses a call to container_pull to return a dependency and
// the position where the version is defined.
func parseContainerPull(call *ast.Call) (Dependency, error) {
	registry, _, err := getCallArgValueString(call, "registry")
	if err != nil {
		return Dependency{}, skerr.Wrap(err)
	}
	repository, _, err := getCallArgValueString(call, "repository")
	if err != nil {
		return Dependency{}, skerr.Wrap(err)
	}
	id := registry + "/" + repository
	digest, digestPos, err := getCallArgValueString(call, "digest")
	if err != nil {
		return Dependency{}, skerr.Wrap(err)
	}
	return Dependency{
		ID:         DependencyID(id),
		Version:    digest,
		versionPos: digestPos,
		SHA256:     digest,
		sha256Pos:  digestPos,
	}, nil
}

// getCallArgValueString searches the keyword arguments of the call for one with
// the matching keyword. If found, it returns the string value of the argument,
// and the position of that string value. This only works for string literals.
func getCallArgValueString(call *ast.Call, keyword string) (string, *ast.Pos, error) {
	for _, kw := range call.Keywords {
		if string(kw.Arg) == keyword {
			if kw.Value.Type().Name == ast.StrType.Name {
				rv := string(kw.Value.(*ast.Str).S)
				if rv == "" {
					return "", nil, skerr.Fmt("found empty string for argument %q", keyword)
				}
				return rv, &ast.Pos{
					Lineno:    kw.Value.GetLineno(),
					ColOffset: kw.Value.GetColOffset(),
				}, nil
			}
		}
	}
	return "", nil, skerr.Fmt("no keyword argument %q found for call", keyword)
}
