// Copyright 2020 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 module defines a framework for extending server.Server with optional
// reusable bundles of functionality (called "modules", naturally).
package module

import (
	"context"

	"google.golang.org/grpc"

	"go.chromium.org/luci/server/auth"
	"go.chromium.org/luci/server/router"
)

// Module represents some optional part of a server.
//
// It is generally a stateful object constructed from some configuration. It can
// be hooked to the server in server.New(...) or server.Main(...).
type Module interface {
	// Name is a name of this module for logs and dependency relations.
	//
	// Usually a package that implements the module registers module's name as
	// a public global variable (so other packages can refer to it) and this
	// method just returns it.
	Name() Name

	// Dependencies returns dependencies (required and optional) of this module.
	Dependencies() []Dependency

	// Initialize is called during the server startup after the core functionality
	// is initialized, but before the server enters the serving loop.
	//
	// The method receives the global server context and can return a derived
	// context which will become the new global server context. That way the
	// module may inject additional state into the context inherited by all
	// requests. If it returns nil, the server context won't be changed.
	//
	// The module may use the context (with all values available there) and the
	// given Host interface to register itself in various server systems. It must
	// not retain 'host': the object it points to becomes invalid after Initialize
	// finishes and using it causes panics. This is intentional.
	//
	// Modules are initialized sequentially in order they are registered. A module
	// observes effects of initialization of all prior modules, e.g. via
	// context.Context.
	//
	// An error causes the process to crash with the corresponding message.
	Initialize(ctx context.Context, host Host, opts HostOptions) (context.Context, error)
}

// HostOptions are options the server was started with.
//
// It is a subset of global server.Options that modules are allowed to use to
// tweak their behavior.
type HostOptions struct {
	Prod         bool   // set when running in production (not on a dev workstation)
	GAE          bool   // set when running on Appengine, implies Prod
	CloudProject string // name of hosting Google Cloud Project if running in GCP
	CloudRegion  string // name of a hosting region (e.g. 'us-central1') if known
}

// Host is part of server.Server API that modules are allowed to use during
// their initialization to inject useful functionality into the server.
//
// TODO(vadimsh):
//  * Allow adding a middleware to the default middleware chain.
type Host interface {
	// ServiceRegistrar is a registrar that can be used to register gRPC services.
	ServiceRegistrar() grpc.ServiceRegistrar

	// Routes returns a router that servers HTTP requests hitting the main port.
	//
	// The module can use it to register additional request handlers.
	//
	// Note that users of server.Server can register more routers through
	// server.AddPort(...) and server.VirtualHost(...). Such application-specific
	// routers are not accessible to modules.
	Routes() *router.Router

	// RunInBackground launches the given callback in a separate goroutine right
	// before starting the serving loop.
	//
	// Should be used for background asynchronous activities like reloading
	// configs.
	//
	// All logs lines emitted by the callback are annotated with "activity" field
	// which can be arbitrary, but by convention has format "<namespace>.<name>",
	// where "luci" namespace is reserved for internal activities.
	//
	// The context passed to the callback is derived from the global server
	// context and it is canceled when the server is shutting down. It is expected
	// the goroutine will exit soon after the context is canceled.
	RunInBackground(activity string, f func(context.Context))

	// RegisterWarmup registers a callback that is run in server's ListenAndServe
	// right before the serving loop.
	//
	// It receives the global server context (including all customizations made
	// by the user code in server.Main). Intended for best-effort warmups: there's
	// no way to gracefully abort the server startup from a warmup callback.
	//
	// All module's essential initialization should happen in its Initialize
	// method instead. The downside is that Initialize runs before the user code
	// in server.Main and it can't depend on modifications done there.
	RegisterWarmup(cb func(context.Context))

	// RegisterCleanup registers a callback that is run in server's ListenAndServe
	// after the server exits the serving loop.
	//
	// It receives the global server context.
	RegisterCleanup(cb func(context.Context))

	// RegisterUnaryServerInterceptor registers an grpc.UnaryServerInterceptor
	// applied to all unary RPCs that hit the server.
	//
	// Interceptors are chained in order they are registered, which matches
	// the order of modules in the list of modules. The first registered
	// interceptor becomes the outermost.
	RegisterUnaryServerInterceptor(intr grpc.UnaryServerInterceptor)

	// RegisterCookieAuth registers an implementation of a cookie-based
	// authentication scheme.
	//
	// If there are multiple such schemes registered, the server will refuse to
	// start.
	RegisterCookieAuth(method auth.Method)
}
