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

import (
	"context"
	"fmt"

	log "go.chromium.org/luci/common/logging"
	cfglib "go.chromium.org/luci/config"
	"go.chromium.org/luci/gae/service/info"
	"go.chromium.org/luci/grpc/grpcutil"
	"go.chromium.org/luci/logdog/api/config/svcconfig"
	"go.chromium.org/luci/logdog/server/config"

	"google.golang.org/grpc/codes"
)

var projectConfigCtxKey = "logdog.coordinator.ProjectConfig"

// WithProjectNamespace sets the current namespace to the project name.
//
// Checks the project exists, but doesn't do any ACL checks.
//
// It will return a user-facing wrapped gRPC error on failure:
//	- InvalidArgument if the project name is invalid.
//	- PermissionDenied/Unauthenticated if the project doesn't exist.
//	- Internal if an internal error occurred.
func WithProjectNamespace(c *context.Context, project string) error {
	ctx := *c

	if err := cfglib.ValidateProjectName(project); err != nil {
		log.WithError(err).Errorf(ctx, "Project name is invalid.")
		return grpcutil.Errf(codes.InvalidArgument, "Project name is invalid: %s", err)
	}

	// Load the project config, thus verifying the project exists.
	pcfg, err := config.ProjectConfig(ctx, project)
	switch {
	case err == cfglib.ErrNoConfig || err == config.ErrInvalidConfig:
		// If the configuration request was valid, but no configuration could be
		// loaded, treat this as the user not having READ access to the project.
		// Otherwise, the user could use this error response to confirm a
		// project's existence.
		log.Fields{
			log.ErrorKey: err,
			"project":    project,
		}.Errorf(ctx, "Could not load config for project.")
		return PermissionDeniedErr(ctx)
	case err != nil:
		// The configuration attempt failed to load. This is an internal error,
		// and is safe to return because it's not contingent on the existence (or
		// lack thereof) of the project.
		return grpcutil.Internal
	}

	// All future datastore queries are scoped to this project.
	pns := ProjectNamespace(project)
	nc, err := info.Namespace(ctx, pns)
	if err != nil {
		log.Fields{
			log.ErrorKey: err,
			"project":    project,
			"namespace":  pns,
		}.Errorf(ctx, "Failed to set namespace.")
		return grpcutil.Internal
	}

	// Store the project config in the context to avoid fetching it again.
	nc = context.WithValue(nc, &projectConfigCtxKey, pcfg)

	*c = nc
	return nil
}

// Project returns the current project installed in the supplied Context's
// namespace.
//
// This function is called with the expectation that the Context is in a
// namespace conforming to ProjectNamespace. If this is not the case, this
// method will panic.
func Project(ctx context.Context) string {
	ns := info.GetNamespace(ctx)
	project := ProjectFromNamespace(ns)
	if project != "" {
		return project
	}
	panic(fmt.Errorf("current namespace %q does not begin with project namespace prefix (%q)", ns, ProjectNamespacePrefix))
}

// ProjectConfig returns the project-specific configuration for the
// current project as set in WithProjectNamespace.
//
// If there is no current project namespace, or if the current project has no
// configuration, config.ErrInvalidConfig will be returned.
func ProjectConfig(ctx context.Context) (*svcconfig.ProjectConfig, error) {
	cfg, _ := ctx.Value(&projectConfigCtxKey).(*svcconfig.ProjectConfig)
	if cfg == nil {
		return nil, config.ErrInvalidConfig
	}
	return cfg, nil
}
