// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package verify

import (
	"encoding/base64"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

const (
	// Copied from the official Google Cloud auto-generated client.
	ProjectRegex         = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?))"
	ProjectRegexWildCard = "(?:(?:[-a-z0-9]{1,63}\\.)*(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?):)?(?:[0-9]{1,19}|(?:[a-z0-9](?:[-a-z0-9]{0,61}[a-z0-9])?)|-)"
	RegionRegex          = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"
	SubnetworkRegex      = "[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?"

	SubnetworkLinkRegex = "projects/(" + ProjectRegex + ")/regions/(" + RegionRegex + ")/subnetworks/(" + SubnetworkRegex + ")$"

	RFC1035NameTemplate = "[a-z](?:[-a-z0-9]{%d,%d}[a-z0-9])"
	CloudIoTIdRegex     = "^[a-zA-Z][-a-zA-Z0-9._+~%]{2,254}$"

	// Format of default Compute service accounts created by Google
	// ${PROJECT_ID}-compute@developer.gserviceaccount.com where PROJECT_ID is an int64 (max 20 digits)
	ComputeServiceAccountNameRegex = "[0-9]{1,20}-compute@developer.gserviceaccount.com"

	// https://cloud.google.com/iam/docs/understanding-custom-roles#naming_the_role
	IAMCustomRoleIDRegex = "^[a-zA-Z0-9_\\.]{3,64}$"

	// https://cloud.google.com/managed-microsoft-ad/reference/rest/v1/projects.locations.global.domains/create#query-parameters
	ADDomainNameRegex = "^[a-z][a-z0-9-]{0,14}\\.[a-z0-9-\\.]*[a-z]+[a-z0-9]*$"
)

var (
	// Service account name must have a length between 6 and 30.
	// The first and last characters have different restrictions, than
	// the middle characters. The middle characters length must be between
	// 4 and 28 since the first and last character are excluded.
	ServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28)

	ServiceAccountLinkRegexPrefix = "projects/" + ProjectRegexWildCard + "/serviceAccounts/"
	PossibleServiceAccountNames   = []string{
		ServiceDefaultAccountNameRegex,
		ComputeServiceAccountNameRegex,
		CreatedServiceAccountNameRegex,
	}
	ServiceAccountLinkRegex = ServiceAccountLinkRegexPrefix + "(" + strings.Join(PossibleServiceAccountNames, "|") + ")"

	ServiceAccountKeyNameRegex = ServiceAccountLinkRegexPrefix + "(.+)/keys/(.+)"

	// Format of service accounts created through the API
	CreatedServiceAccountNameRegex = fmt.Sprintf(RFC1035NameTemplate, 4, 28) + "@" + ProjectNameInDNSFormRegex + "\\.iam\\.gserviceaccount\\.com$"

	// Format of service-created service account
	// examples are:
	// 		$PROJECTID@cloudbuild.gserviceaccount.com
	// 		$PROJECTID@cloudservices.gserviceaccount.com
	// 		$PROJECTID@appspot.gserviceaccount.com
	ServiceDefaultAccountNameRegex = ProjectRegex + "@[a-z]+.gserviceaccount.com$"

	ProjectNameInDNSFormRegex = "[-a-z0-9\\.]{1,63}"
	ProjectNameRegex          = "^[A-Za-z0-9-'\"\\s!]{4,30}$"

	// Valid range for Cloud Router ASN values as per RFC6996
	// https://tools.ietf.org/html/rfc6996
	// Must be explicitly int64 to avoid overflow when building Terraform for 32bit architectures
	Rfc6996Asn16BitMin  = int64(64512)
	Rfc6996Asn16BitMax  = int64(65534)
	Rfc6996Asn32BitMin  = int64(4200000000)
	Rfc6996Asn32BitMax  = int64(4294967294)
	GcpRouterPartnerAsn = int64(16550)

	// Format of GCS Bucket Name
	// https://cloud.google.com/storage/docs/naming-buckets
	GCSNameValidChars     = "^[a-z0-9_.-]*$"
	GCSNameStartEndChars  = "^[a-z|0-9].*[a-z|0-9]$"
	GCSNameLength         = "^.{3,222}"
	GCSNameLengthSplit    = "^.{1,63}$"
	GCSNameCidr           = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$"
	GCSNameGoogPrefix     = "^goog.*$"
	GCSNameContainsGoogle = "^.*google.*$"
)

var Rfc1918Networks = []string{
	"10.0.0.0/8",
	"172.16.0.0/12",
	"192.168.0.0/16",
}

// validateGCEName ensures that a field matches the requirements for Compute Engine resource names
// https://cloud.google.com/compute/docs/naming-resources#resource-name-format
func ValidateGCEName(v interface{}, k string) (ws []string, errors []error) {
	re := `^(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)$`
	return ValidateRegexp(re)(v, k)
}

// validateGCSName ensures the name of a gcs bucket matches the requirements for GCS Buckets
// https://cloud.google.com/storage/docs/naming-buckets
func ValidateGCSName(v interface{}, k string) (ws []string, errors []error) {
	value := v.(string)

	if !regexp.MustCompile(GCSNameValidChars).MatchString(value) {
		errors = append(errors, fmt.Errorf("%q name value can only contain lowercase letters, numeric characters, dashes (-), underscores (_), and dots (.)", value))
	}

	if !regexp.MustCompile(GCSNameStartEndChars).MatchString(value) {
		errors = append(errors, fmt.Errorf("%q name value must start and end with a number or letter", value))
	}

	if !regexp.MustCompile(GCSNameLength).MatchString(value) {
		errors = append(errors, fmt.Errorf("%q name value must contain 3-63 characters. Names containing dots can contain up to 222 characters, but each dot-separated component can be no longer than 63 characters", value))
	}

	for _, str := range strings.Split(value, ".") {
		if !regexp.MustCompile(GCSNameLengthSplit).MatchString(str) {
			errors = append(errors, fmt.Errorf("%q name value must contain 3-63 characters. Names containing dots can contain up to 222 characters, but each dot-separated component can be no longer than 63 characters", value))
		}
	}

	if regexp.MustCompile(GCSNameCidr).MatchString(value) {
		errors = append(errors, fmt.Errorf("%q name value cannot be represented as an IP address in dotted-decimal notation (for example, 192.168.5.4)", value))
	}

	if regexp.MustCompile(GCSNameGoogPrefix).MatchString(value) {
		errors = append(errors, fmt.Errorf("%q name value cannot begin with the \"goog\" prefix", value))
	}

	if regexp.MustCompile(GCSNameContainsGoogle).MatchString(strings.ReplaceAll(value, "0", "o")) {
		errors = append(errors, fmt.Errorf("%q name value cannot contain \"google\" or close misspellings, such as \"g00gle\"", value))
	}

	return
}

// Ensure that the BGP ASN value of Cloud Router is a valid value as per RFC6996 or a value of 16550
func ValidateRFC6996Asn(v interface{}, k string) (ws []string, errors []error) {
	value := int64(v.(int))
	if !(value >= Rfc6996Asn16BitMin && value <= Rfc6996Asn16BitMax) &&
		!(value >= Rfc6996Asn32BitMin && value <= Rfc6996Asn32BitMax) &&
		value != GcpRouterPartnerAsn {
		errors = append(errors, fmt.Errorf(`expected %q to be a RFC6996-compliant Local ASN:
must be either in the private ASN ranges: [64512..65534], [4200000000..4294967294];
or be the value of [%d], got %d`, k, GcpRouterPartnerAsn, value))
	}
	return
}

func ValidateEnum(values []string) schema.SchemaValidateFunc {
	return validation.StringInSlice(values, false)
}

func ValidateRFC1918Network(min, max int) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {

		s, es = validation.IsCIDRNetwork(min, max)(i, k)
		if len(es) > 0 {
			return
		}

		v, _ := i.(string)
		ip, _, _ := net.ParseCIDR(v)
		for _, c := range Rfc1918Networks {
			if _, ipnet, _ := net.ParseCIDR(c); ipnet.Contains(ip) {
				return
			}
		}

		es = append(es, fmt.Errorf("expected %q to be an RFC1918-compliant CIDR, got: %s", k, v))

		return
	}
}

func ValidateRFC3339Time(v interface{}, k string) (warnings []string, errors []error) {
	time := v.(string)
	if len(time) != 5 || time[2] != ':' {
		errors = append(errors, fmt.Errorf("%q (%q) must be in the format HH:mm (RFC3339)", k, time))
		return
	}
	if hour, err := strconv.ParseUint(time[:2], 10, 0); err != nil || hour > 23 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid hour (00-23)", k, time))
		return
	}
	if min, err := strconv.ParseUint(time[3:], 10, 0); err != nil || min > 59 {
		errors = append(errors, fmt.Errorf("%q (%q) does not contain a valid minute (00-59)", k, time))
		return
	}
	return
}

func ValidateRFC1035Name(min, max int) schema.SchemaValidateFunc {
	if min < 2 || max < min {
		return func(i interface{}, k string) (s []string, errors []error) {
			if min < 2 {
				errors = append(errors, fmt.Errorf("min must be at least 2. Got: %d", min))
			}
			if max < min {
				errors = append(errors, fmt.Errorf("max must greater than min. Got [%d, %d]", min, max))
			}
			return
		}
	}

	return ValidateRegexp(fmt.Sprintf("^"+RFC1035NameTemplate+"$", min-2, max-2))
}

func ValidateIpCidrRange(v interface{}, k string) (warnings []string, errors []error) {
	_, _, err := net.ParseCIDR(v.(string))
	if err != nil {
		errors = append(errors, fmt.Errorf("%q is not a valid IP CIDR range: %s", k, err))
	}
	return
}

func ValidateIAMCustomRoleID(v interface{}, k string) (warnings []string, errors []error) {
	value := v.(string)
	if !regexp.MustCompile(IAMCustomRoleIDRegex).MatchString(value) {
		errors = append(errors, fmt.Errorf(
			"%q (%q) doesn't match regexp %q", k, value, IAMCustomRoleIDRegex))
	}
	return
}

func OrEmpty(f schema.SchemaValidateFunc) schema.SchemaValidateFunc {
	return func(i interface{}, k string) ([]string, []error) {
		v, ok := i.(string)
		if ok && v == "" {
			return nil, nil
		}
		return f(i, k)
	}
}

func ValidateProjectID() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile("^" + ProjectRegex + "$").MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q project_id must be 6 to 30 with lowercase letters, digits, hyphens and start with a letter. Trailing hyphens are prohibited.", value))
		}
		return
	}
}

func ValidateDSProjectID() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)
		ids := strings.Split(value, "/")
		value = ids[len(ids)-1]

		if !regexp.MustCompile("^" + ProjectRegex + "$").MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q project_id must be 6 to 30 with lowercase letters, digits, hyphens and start with a letter. Trailing hyphens are prohibited.", value))
		}
		return
	}
}

func ValidateProjectName() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if !regexp.MustCompile(ProjectNameRegex).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q name must be 4 to 30 characters with lowercase and uppercase letters, numbers, hyphen, single-quote, double-quote, space, and exclamation point.", value))
		}
		return
	}
}

func ValidateDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		if _, err := time.ParseDuration(v); err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		return
	}
}

func ValidateNonNegativeDuration() schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		dur, err := time.ParseDuration(v)
		if err != nil {
			es = append(es, fmt.Errorf("expected %s to be a duration, but parsing gave an error: %s", k, err.Error()))
			return
		}

		if dur < 0 {
			es = append(es, fmt.Errorf("duration %v must be a non-negative duration", dur))
			return
		}

		return
	}
}

func ValidateIpAddress(i interface{}, val string) ([]string, []error) {
	ip := net.ParseIP(i.(string))
	if ip == nil {
		return nil, []error{fmt.Errorf("could not parse %q to IP address", val)}
	}
	return nil, nil
}

func ValidateBase64String(i interface{}, val string) ([]string, []error) {
	_, err := base64.StdEncoding.DecodeString(i.(string))
	if err != nil {
		return nil, []error{fmt.Errorf("could not decode %q as a valid base64 value. Please use the terraform base64 functions such as base64encode() or filebase64() to supply a valid base64 string", val)}
	}
	return nil, nil
}

// StringNotInSlice returns a SchemaValidateFunc which tests if the provided value
// is of type string and that it matches none of the element in the invalid slice.
// if ignorecase is true, case is ignored.
func StringNotInSlice(invalid []string, ignoreCase bool) schema.SchemaValidateFunc {
	return func(i interface{}, k string) (s []string, es []error) {
		v, ok := i.(string)
		if !ok {
			es = append(es, fmt.Errorf("expected type of %s to be string", k))
			return
		}

		for _, str := range invalid {
			if v == str || (ignoreCase && strings.ToLower(v) == strings.ToLower(str)) {
				es = append(es, fmt.Errorf("expected %s to not match any of %v, got %s", k, invalid, v))
				return
			}
		}

		return
	}
}

// Ensure that hourly timestamp strings "HH:MM" have the minutes zeroed out for hourly only inputs
func ValidateHourlyOnly(val interface{}, key string) (warns []string, errs []error) {
	v := val.(string)
	parts := strings.Split(v, ":")
	if len(parts) != 2 {
		errs = append(errs, fmt.Errorf("%q must be in the format HH:00, got: %s", key, v))
		return
	}
	if parts[1] != "00" {
		errs = append(errs, fmt.Errorf("%q does not allow minutes, it must be in the format HH:00, got: %s", key, v))
	}
	i, err := strconv.Atoi(parts[0])
	if err != nil {
		errs = append(errs, fmt.Errorf("%q cannot be parsed, it must be in the format HH:00, got: %s", key, v))
	} else if i < 0 || i > 23 {
		errs = append(errs, fmt.Errorf("%q does not specify a valid hour, it must be in the format HH:00 where HH : [00-23], got: %s", key, v))
	}
	return
}

func ValidateRFC3339Date(v interface{}, k string) (warnings []string, errors []error) {
	_, err := time.Parse(time.RFC3339, v.(string))
	if err != nil {
		errors = append(errors, err)
	}
	return
}

func ValidateADDomainName() schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)

		if len(value) > 64 || !regexp.MustCompile(ADDomainNameRegex).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q (%q) doesn't match regexp %q, domain_name must be 2 to 64 with lowercase letters, digits, hyphens, dots and start with a letter", k, value, ADDomainNameRegex))
		}
		return
	}
}

func TestStringValidationCases(cases []StringValidationTestCase, validationFunc schema.SchemaValidateFunc) []error {
	es := make([]error, 0)
	for _, c := range cases {
		es = append(es, TestStringValidation(c, validationFunc)...)
	}

	return es
}

func TestStringValidation(testCase StringValidationTestCase, validationFunc schema.SchemaValidateFunc) []error {
	_, es := validationFunc(testCase.Value, testCase.TestName)
	if testCase.ExpectError {
		if len(es) > 0 {
			return nil
		} else {
			return []error{fmt.Errorf("Didn't see expected error in case \"%s\" with string \"%s\"", testCase.TestName, testCase.Value)}
		}
	}

	return es
}

type StringValidationTestCase struct {
	TestName    string
	Value       string
	ExpectError bool
}

func ValidateRegexp(re string) schema.SchemaValidateFunc {
	return func(v interface{}, k string) (ws []string, errors []error) {
		value := v.(string)
		if !regexp.MustCompile(re).MatchString(value) {
			errors = append(errors, fmt.Errorf(
				"%q (%q) doesn't match regexp %q", k, value, re))
		}

		return
	}
}
