package main

import (
	"net/http"

	"go.chromium.org/luci/server"
	"go.chromium.org/luci/server/auth"
	"go.chromium.org/luci/server/encryptedcookies"
	"go.chromium.org/luci/server/module"
	"go.chromium.org/luci/server/router"

	adminapi "go.chromium.org/luci/cipd/api/admin/v1"
	pubapi "go.chromium.org/luci/cipd/api/cipd/v1"
	"go.chromium.org/luci/cipd/appengine/impl"
	"go.chromium.org/luci/cipd/appengine/impl/accesslog"
	"go.chromium.org/luci/cipd/appengine/ui"

	// Using datastore for user sessions.
	_ "go.chromium.org/luci/server/encryptedcookies/session/datastore"
	// Using transactional datastore TQ tasks.
	_ "go.chromium.org/luci/server/tq/txn/datastore"
)

func main() {
	// Extra modules used by the frontend server only.
	extra := []module.Module{
		encryptedcookies.NewModuleFromFlags(),
	}

	impl.Main(extra, func(srv *server.Server, svc *impl.Services) error {
		// Register non-pRPC routes, such as the client bootstrap handler and routes
		// to support minimal subset of legacy API required to let old CIPD clients
		// fetch packages and self-update.
		svc.PublicRepo.InstallHandlers(srv.Routes, router.NewMiddlewareChain(
			auth.Authenticate(&auth.GoogleOAuth2Method{
				Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"},
			}),
		))

		// UI pages. When running locally, serve static files ourself as well.
		ui.InstallHandlers(srv, svc, "templates")
		if !srv.Options.Prod {
			srv.Routes.Static("/static", nil, http.Dir("./static"))
		}

		// All pRPC services.
		adminapi.RegisterAdminServer(srv.PRPC, svc.AdminAPI)
		pubapi.RegisterStorageServer(srv.PRPC, svc.PublicCAS)
		pubapi.RegisterRepositoryServer(srv.PRPC, svc.PublicRepo)

		// Log RPC requests to BigQuery.
		srv.PRPC.UnaryServerInterceptor = accesslog.NewUnaryServerInterceptor(&srv.Options)

		return nil
	})
}
