/* Copyright 2016 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 label provides utilities for parsing and manipulating
// Bazel labels. See
// https://docs.bazel.build/versions/master/build-ref.html#labels
// for more information.
package label

import (
	"fmt"
	"log"
	"path"
	"regexp"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/pathtools"
)

// A Label represents a label of a build target in Bazel. Labels have three
// parts: a repository name, a package name, and a target name, formatted
// as @repo//pkg:target.
type Label struct {
	// Repo is the repository name. If omitted, the label refers to a target
	// in the current repository.
	Repo string

	// Pkg is the package name, which is usually the directory that contains
	// the target. If both Repo and Pkg are omitted, the label is relative.
	Pkg string

	// Name is the name of the target the label refers to. Name must not be empty.
	// Note that the name may be omitted from a label string if it is equal to
	// the last component of the package name ("//x" is equivalent to "//x:x"),
	// but in either case, Name should be set here.
	Name string

	// Relative indicates whether the label refers to a target in the current
	// package. Relative is true if and only if Repo and Pkg are both omitted.
	Relative bool
}

// New constructs a new label from components.
func New(repo, pkg, name string) Label {
	return Label{Repo: repo, Pkg: pkg, Name: name}
}

// NoLabel is the zero value of Label. It is not a valid label and may be
// returned when an error occurs.
var NoLabel = Label{}

var (
	// This was taken from https://github.com/bazelbuild/bazel/blob/71fb1e4188b01e582a308cfe4bcbf1c730eded1b/src/main/java/com/google/devtools/build/lib/cmdline/RepositoryName.java#L159C1-L164
	labelRepoRegexp = regexp.MustCompile(`^@$|^[A-Za-z0-9_.-][A-Za-z0-9_.~-]*$`)
	// This was taken from https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/cmdline/LabelValidator.java
	// Package names may contain all 7-bit ASCII characters except:
	// 0-31 (control characters)
	// 58 ':' (colon) - target name separator
	// 92 '\' (backslash) - directory separator (on Windows); may be allowed in the future
	// 127 (delete)
	// Target names may contain the same characters
	labelPkgRegexp  = regexp.MustCompile(`^[\x20-\x39\x3B-\x5B\x5D-\x7E]*$`)
	labelNameRegexp = labelPkgRegexp
)

// Parse reads a label from a string.
// See https://docs.bazel.build/versions/master/build-ref.html#lexi.
func Parse(s string) (Label, error) {
	origStr := s

	relative := true
	var repo string
	// if target name begins @@ drop the first @
	if strings.HasPrefix(s, "@@") {
		s = s[len("@"):]
	}
	if strings.HasPrefix(s, "@") {
		relative = false
		endRepo := strings.Index(s, "//")
		if endRepo > len("@") {
			repo = s[len("@"):endRepo]
			s = s[endRepo:]
			// If the label begins with "@//...", set repo = "@"
			// to remain distinct from "//...", where repo = ""
		} else if endRepo == len("@") {
			repo = s[:len("@")]
			s = s[len("@"):]
		} else {
			repo = s[len("@"):]
			s = "//:" + repo
		}
		if !labelRepoRegexp.MatchString(repo) {
			return NoLabel, fmt.Errorf("label parse error: repository has invalid characters: %q", origStr)
		}
	}

	var pkg string
	if strings.HasPrefix(s, "//") {
		relative = false
		endPkg := strings.Index(s, ":")
		if endPkg < 0 {
			pkg = s[len("//"):]
			s = ""
		} else {
			pkg = s[len("//"):endPkg]
			s = s[endPkg:]
		}
		if !labelPkgRegexp.MatchString(pkg) {
			return NoLabel, fmt.Errorf("label parse error: package has invalid characters: %q", origStr)
		}
	}

	if s == ":" {
		return NoLabel, fmt.Errorf("label parse error: empty name: %q", origStr)
	}
	name := strings.TrimPrefix(s, ":")
	if !labelNameRegexp.MatchString(name) {
		return NoLabel, fmt.Errorf("label parse error: name has invalid characters: %q", origStr)
	}

	if pkg == "" && name == "" {
		return NoLabel, fmt.Errorf("label parse error: empty package and name: %q", origStr)
	}
	if name == "" {
		name = path.Base(pkg)
	}

	return Label{
		Repo:     repo,
		Pkg:      pkg,
		Name:     name,
		Relative: relative,
	}, nil
}

func (l Label) String() string {
	if l.Relative {
		return fmt.Sprintf(":%s", l.Name)
	}

	var repo string
	if l.Repo != "" && l.Repo != "@" {
		repo = fmt.Sprintf("@%s", l.Repo)
	} else {
		// if l.Repo == "", the label string will begin with "//"
		// if l.Repo == "@", the label string will begin with "@//"
		repo = l.Repo
	}

	if path.Base(l.Pkg) == l.Name {
		return fmt.Sprintf("%s//%s", repo, l.Pkg)
	}
	return fmt.Sprintf("%s//%s:%s", repo, l.Pkg, l.Name)
}

// Abs computes an absolute label (one with a repository and package name)
// from this label. If this label is already absolute, it is returned
// unchanged.
func (l Label) Abs(repo, pkg string) Label {
	if !l.Relative {
		return l
	}
	return Label{Repo: repo, Pkg: pkg, Name: l.Name}
}

// Rel attempts to compute a relative label from this label. If this label
// is already relative or is in a different package, this label may be
// returned unchanged.
func (l Label) Rel(repo, pkg string) Label {
	if l.Relative || l.Repo != repo {
		return l
	}
	if l.Pkg == pkg {
		return Label{Name: l.Name, Relative: true}
	}
	return Label{Pkg: l.Pkg, Name: l.Name}
}

// Equal returns whether two labels are exactly the same. It does not return
// true for different labels that refer to the same target.
func (l Label) Equal(other Label) bool {
	return l.Repo == other.Repo &&
		l.Pkg == other.Pkg &&
		l.Name == other.Name &&
		l.Relative == other.Relative
}

// Contains returns whether other is contained by the package of l or a
// sub-package. Neither label may be relative.
func (l Label) Contains(other Label) bool {
	if l.Relative {
		log.Panicf("l must not be relative: %s", l)
	}
	if other.Relative {
		log.Panicf("other must not be relative: %s", other)
	}
	result := l.Repo == other.Repo && pathtools.HasPrefix(other.Pkg, l.Pkg)
	return result
}

var nonWordRe = regexp.MustCompile(`\W+`)

// ImportPathToBazelRepoName converts a Go import path into a bazel repo name
// following the guidelines in http://bazel.io/docs/be/functions.html#workspace
func ImportPathToBazelRepoName(importpath string) string {
	importpath = strings.ToLower(importpath)
	components := strings.Split(importpath, "/")
	labels := strings.Split(components[0], ".")
	reversed := make([]string, 0, len(labels)+len(components)-1)
	for i := range labels {
		l := labels[len(labels)-i-1]
		reversed = append(reversed, l)
	}
	repo := strings.Join(append(reversed, components[1:]...), ".")
	return nonWordRe.ReplaceAllString(repo, "_")
}
