// Copyright 2015 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 authdb

import (
	"fmt"
	"net"

	"go.chromium.org/luci/auth/identity"

	"go.chromium.org/luci/server/auth/service/protocol"
)

// validateAuthDB returns nil if AuthDB looks correct.
func validateAuthDB(db *protocol.AuthDB) error {
	groups := make(map[string]*protocol.AuthGroup, len(db.Groups))
	for _, g := range db.Groups {
		groups[g.Name] = g
	}
	for name := range groups {
		if err := validateAuthGroup(name, groups); err != nil {
			return err
		}
	}
	for _, l := range db.IpWhitelists {
		if err := validateIPAllowlist(l); err != nil {
			return fmt.Errorf("auth: bad IP allowlist %q - %s", l.Name, err)
		}
	}
	if db.Realms != nil {
		perms := uint32(len(db.Realms.Permissions))
		conds := uint32(len(db.Realms.Conditions))
		for _, realm := range db.Realms.Realms {
			if err := validateRealm(realm, perms, conds); err != nil {
				return fmt.Errorf("auth: bad realm %q - %s", realm.Name, err)
			}
		}
	}
	return nil
}

// validateAuthGroup returns nil if AuthGroup looks correct.
func validateAuthGroup(name string, groups map[string]*protocol.AuthGroup) error {
	g := groups[name]

	for _, ident := range g.Members {
		if _, err := identity.MakeIdentity(ident); err != nil {
			return fmt.Errorf("auth: invalid identity %q in group %q - %s", ident, name, err)
		}
	}

	for _, glob := range g.Globs {
		if _, err := identity.MakeGlob(glob); err != nil {
			return fmt.Errorf("auth: invalid glob %q in group %q - %s", glob, name, err)
		}
	}

	for _, nested := range g.Nested {
		if groups[nested] == nil {
			return fmt.Errorf("auth: unknown nested group %q in group %q", nested, name)
		}
	}

	if cycle := findGroupCycle(name, groups); len(cycle) != 0 {
		return fmt.Errorf("auth: dependency cycle found - %v", cycle)
	}

	return nil
}

// findGroupCycle searches for a group dependency cycle that contains group
// `name`. Returns list of groups that form the cycle if found, empty list
// if no cycles. Unknown groups are considered empty.
func findGroupCycle(name string, groups map[string]*protocol.AuthGroup) []string {
	// Set of groups that are completely explored (all subtree is traversed).
	visited := map[string]bool{}

	// Stack of groups that are being explored now. In case a cycle is detected
	// it would contain that cycle.
	var visiting []string

	// Recursively explores `group` subtree, returns true if finds a cycle.
	var visit func(string) bool
	visit = func(group string) bool {
		g := groups[group]
		if g == nil {
			visited[group] = true
			return false
		}
		visiting = append(visiting, group)
		for _, nested := range g.GetNested() {
			// Cross edge. Can happen in diamond-like graph, not a cycle.
			if visited[nested] {
				continue
			}
			// Is `group` references its own ancestor -> cycle is detected.
			for _, v := range visiting {
				if v == nested {
					return true
				}
			}
			// Explore subtree.
			if visit(nested) {
				return true
			}
		}
		visiting = visiting[:len(visiting)-1]
		visited[group] = true
		return false
	}

	visit(name)
	return visiting // will contain a cycle, if any
}

// validateIPAllowlist checks IPs in the allowlist are parsable.
func validateIPAllowlist(l *protocol.AuthIPWhitelist) error {
	for _, subnet := range l.Subnets {
		if _, _, err := net.ParseCIDR(subnet); err != nil {
			return fmt.Errorf("bad subnet %q - %s", subnet, err)
		}
	}
	return nil
}

// validateRealm checks indexes of permissions and conditions in bindings.
func validateRealm(r *protocol.Realm, permsCount, condsCount uint32) error {
	for _, b := range r.Bindings {
		for _, perm := range b.Permissions {
			if perm >= permsCount {
				return fmt.Errorf("referencing out-of-bounds permission: %d>=%d", perm, permsCount)
			}
		}
		for _, cond := range b.Conditions {
			if cond >= condsCount {
				return fmt.Errorf("referencing out-of-bounds condition: %d>=%d", cond, condsCount)
			}
		}
	}
	return nil
}
