// Copyright 2018 The LUCI Authors.
//
// 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 protoutil

import (
	"fmt"
	"regexp"
	"strings"

	pb "go.chromium.org/luci/buildbucket/proto"
	"go.chromium.org/luci/common/errors"
)

var (
	projRegex    = regexp.MustCompile(`^[a-z0-9\-_]+$`)
	bucketRegex  = regexp.MustCompile(`^[a-z0-9\-_.]{1,100}$`)
	builderRegex = regexp.MustCompile(`^[a-zA-Z0-9\-_.\(\) ]{1,128}$`)
)

// ValidateBuilderID validates the given builder ID.
// Bucket and Builder are optional and only validated if specified.
func ValidateBuilderID(b *pb.BuilderID) error {
	switch parts := strings.Split(b.GetBucket(), "."); {
	case !projRegex.MatchString(b.GetProject()):
		return errors.Reason("project must match %q", projRegex).Err()
	case b.GetBucket() != "" && !bucketRegex.MatchString(b.Bucket):
		return errors.Reason("bucket must match %q", bucketRegex).Err()
	case b.GetBuilder() != "" && !builderRegex.MatchString(b.Builder):
		return errors.Reason("builder must match %q", builderRegex).Err()
	case b.GetBucket() != "" && parts[0] == "luci" && len(parts) > 2:
		return errors.Reason("invalid use of v1 bucket in v2 API (hint: try %q)", parts[2]).Err()
	default:
		return nil
	}
}

// ValidateRequiredBuilderID validates the given builder ID, requiring Bucket
// and Builder.
func ValidateRequiredBuilderID(b *pb.BuilderID) error {
	switch err := ValidateBuilderID(b); {
	case err != nil:
		return err
	case b.Bucket == "":
		return errors.Reason("bucket is required").Err()
	case b.Builder == "":
		return errors.Reason("builder is required").Err()
	default:
		return nil
	}
}

// FormatBuilderID returns "{project}/{bucket}/{builder}" string.
func FormatBuilderID(id *pb.BuilderID) string {
	return fmt.Sprintf("%s/%s/%s", id.Project, id.Bucket, id.Builder)
}

// ParseBuilderID parses a "{project}/{bucket}/{builder}" string.
// Opposite of FormatBuilderID.
func ParseBuilderID(s string) (*pb.BuilderID, error) {
	parts := strings.Split(s, "/")
	if len(parts) != 3 {
		return nil, fmt.Errorf("invalid builder id; must have 2 slashes")
	}
	return &pb.BuilderID{
		Project: parts[0],
		Bucket:  parts[1],
		Builder: parts[2],
	}, nil
}

// FormatBucketID returns "{project}/{bucket}" string.
func FormatBucketID(project, bucket string) string {
	return fmt.Sprintf("%s/%s", project, bucket)
}

// ParseBucketID parses a "{project}/{bucket}" string.
// Opposite of FormatBucketID.
func ParseBucketID(s string) (string, string, error) {
	switch parts := strings.Split(s, "/"); {
	case len(parts) != 2:
		return "", "", errors.New("invalid bucket id; must have 1 slash")
	case strings.TrimSpace(parts[0]) == "":
		return "", "", errors.New("invalid bucket id; project is empty")
	case strings.TrimSpace(parts[1]) == "":
		return "", "", errors.New("invalid bucket id; bucket is empty")
	default:
		return parts[0], parts[1], nil
	}
}
