package main

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"
)

func main() {
	policy := "/osb/v2/service_instances/{instance_id}/service_bindings/{binding_id}/last_operation"
	pathGood := "/osb/v2/service_instances/foo/service_bindings/bar/last_operation"
	pathBad := "/osb/v2/service_instances/foo/evil_path/service_bindings/bar/last_operation"
	pathShort := "/osb/v2/service_instances/foo_bar/"

	fmt.Printf("Valid Path: %s\n", strconv.FormatBool(checkPolicyMatch(policy, pathGood)))
	fmt.Printf("Valid Path: %s\n", strconv.FormatBool(checkPolicyMatch(policy, pathBad)))
	fmt.Printf("Valid Path: %s\n", strconv.FormatBool(checkPolicyMatch(policy, pathShort)))
}

func checkPolicyMatch(policy, path string) bool {
	// split the path elements by "/"
	policyElements := strings.Split(policy, "/")
	pathElements := strings.Split(path, "/")

	// check to see if the number of elements are present in the path to prevent index out of range error
	if len(policyElements) > len(pathElements) {
		return false
	}

	// check each path element
	for i := 0; i < len(policyElements); i++ {
		switch {
		// policy matching wildcard **
		case regexp.MustCompile(`^\*\*$`).MatchString(policyElements[i]):
			continue
		// policy matching wildcard {foo}
		case regexp.MustCompile(`^\{.+\}$`).MatchString(policyElements[i]):
			continue
		// path matches exactly, should we ignore case with EqualFold()
		case policyElements[i] == pathElements[i]:
			continue
		// default deny
		default:
			return false
		}
	}

	return true
}