// 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 repo

import (
	"context"
	"strings"

	"go.chromium.org/luci/auth/identity"
	"go.chromium.org/luci/common/data/stringset"
	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/server/auth"

	api "go.chromium.org/luci/cipd/api/cipd/v1"
)

// impliedRoles defines what roles are "inherited" by other roles, e.g.
// WRITERs are automatically READERs, so hasRole(..., READER) should return true
// for WRITERs too.
//
// The format is "role -> {role itself} + set of roles implied by it, perhaps
// indirectly".
//
// If a role is missing from this map, it assumed to not be implying any roles.
var impliedRoles = map[api.Role][]api.Role{
	api.Role_READER: {api.Role_READER},
	api.Role_WRITER: {api.Role_WRITER, api.Role_READER},
	api.Role_OWNER:  {api.Role_OWNER, api.Role_WRITER, api.Role_READER},
}

// impliedRolesRev is reverse of impliedRoles mapping.
//
// The format is "role -> {role itself} + set of roles that inherit it, perhaps
// indirectly".
//
// If a role is missing from this map, it assumed to not be inherited by
// anything.
var impliedRolesRev = map[api.Role]map[api.Role]struct{}{
	api.Role_READER: roleSet(api.Role_READER, api.Role_WRITER, api.Role_OWNER),
	api.Role_WRITER: roleSet(api.Role_WRITER, api.Role_OWNER),
	api.Role_OWNER:  roleSet(api.Role_OWNER),
}

func roleSet(roles ...api.Role) map[api.Role]struct{} {
	m := make(map[api.Role]struct{}, len(roles))
	for _, r := range roles {
		m[r] = struct{}{}
	}
	return m
}

// hasRole checks whether the current caller has the given role in any of the
// supplied PrefixMetadata objects.
//
// It understands the role inheritance defined by impliedRoles map.
//
// 'metas' is metadata for some prefix and all parent prefixes. It is expected
// to be ordered by the prefix length (shortest first). Ordering is not really
// used now, but it may change in the future.
//
// Returns only transient errors.
func hasRole(ctx context.Context, metas []*api.PrefixMetadata, role api.Role) (bool, error) {
	caller := string(auth.CurrentIdentity(ctx)) // e.g. "user:abc@example.com"

	// E.g. if 'role' is READER, 'roles' will be {READER, WRITER, OWNER}.
	roles := impliedRolesRev[role]
	if roles == nil {
		roles = roleSet(role)
	}

	// Enumerate the set of principals that have any of the requested roles in any
	// of the prefixes. Exit early if hitting the direct match, otherwise proceed
	// to more expensive group membership checks. Note that we don't use isInACL
	// here because we want to postpone all group checks until the very end,
	// checking memberships in all groups mentioned in 'metas' at once.
	groups := stringset.New(10) // 10 is picked arbitrarily
	for _, meta := range metas {
		for _, acl := range meta.Acls {
			if _, ok := roles[acl.Role]; !ok {
				continue // not the role we are interested in
			}
			for _, p := range acl.Principals {
				if p == caller {
					return true, nil // the caller was specified in ACLs explicitly
				}
				// Is this a reference to a group?
				if s := strings.SplitN(p, ":", 2); len(s) == 2 && s[0] == "group" {
					groups.Add(s[1])
				}
			}
		}
	}

	yes, err := auth.IsMember(ctx, groups.ToSlice()...)
	if err != nil {
		return false, errors.Annotate(err, "failed to check group memberships when checking ACLs for role %s", role).Err()
	}
	return yes, nil
}

// rolesInPrefix returns a union of roles `ident` has in given supplied
// PrefixMetadata objects.
//
// It understands the role inheritance defined by impliedRoles map.
//
// Returns only transient errors.
func rolesInPrefix(ctx context.Context, ident identity.Identity, metas []*api.PrefixMetadata) ([]api.Role, error) {
	roles := roleSet()
	for _, meta := range metas {
		for _, acl := range meta.Acls {
			if _, ok := roles[acl.Role]; ok {
				continue // seen this role already
			}
			switch yes, err := isInACL(ctx, ident, acl); {
			case err != nil:
				return nil, err
			case yes:
				// Add acl.Role and all roles implied by it to 'roles' set.
				for _, r := range impliedRoles[acl.Role] {
					roles[r] = struct{}{}
				}
			}
		}
	}

	// Arrange the result in the order of Role enum definition.
	out := make([]api.Role, 0, len(roles))
	for r := api.Role_READER; r <= api.Role_OWNER; r++ {
		if _, ok := roles[r]; ok {
			out = append(out, r)
		}
	}
	return out, nil
}

// isInACL is true if `ident` is in the given access control list.
//
// Most callers will use auth.CurrentIdentity() for this value.
func isInACL(ctx context.Context, ident identity.Identity, acl *api.PrefixMetadata_ACL) (bool, error) {
	var groups []string
	for _, p := range acl.Principals {
		if p == string(ident) {
			return true, nil // the identity was specified in ACLs explicitly
		}
		if s := strings.SplitN(p, ":", 2); len(s) == 2 && s[0] == "group" {
			groups = append(groups, s[1])
		}
	}

	// We don't use auth.IsMember because we want to check for `ident` rather than
	// for the current caller.
	var yes bool
	var err error
	if s := auth.GetState(ctx); s != nil {
		yes, err = s.DB().IsMember(ctx, ident, groups)
	} else {
		err = auth.ErrNotConfigured
	}
	if err != nil {
		return false, errors.Annotate(err, "failed to check group memberships when checking ACLs").Err()
	}
	return yes, nil
}
