// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// HTTP server that uses OAuth to create security.Blessings objects.
package server

import (
	"crypto/rand"
	"fmt"
	mrand "math/rand"
	"net"
	"net/http"
	"reflect"
	"strconv"
	"strings"
	"syscall"
	"time"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/v23/naming"
	"v.io/v23/rpc"
	"v.io/v23/security"
	"v.io/v23/verror"
	"v.io/x/lib/vlog"

	"v.io/x/ref/lib/signals"
	"v.io/x/ref/security/audit"
	"v.io/x/ref/services/identity/internal/auditor"
	"v.io/x/ref/services/identity/internal/blesser"
	"v.io/x/ref/services/identity/internal/caveats"
	"v.io/x/ref/services/identity/internal/handlers"
	"v.io/x/ref/services/identity/internal/oauth"
	"v.io/x/ref/services/identity/internal/revocation"
	"v.io/x/ref/services/identity/internal/templates"
	"v.io/x/ref/services/identity/internal/util"
	services "v.io/x/ref/services/security"
	"v.io/x/ref/services/security/discharger"
)

const (
	// TODO(ataly, ashankar, suharshs): The name "google" for the oauthBlesserService does
	// not seem appropriate given our modular construction of the identity server. The
	// oauthBlesserService can use any oauthProvider of its choosing, i.e., it does not
	// always have to be "google". One option would be change the value to "oauth". This
	// would also make the name analogous to that of macaroonService. Note that this option
	// also requires changing the extension.
	oauthBlesserService = "google"
	macaroonService     = "macaroon"
	dischargerService   = "discharger"
)

type IdentityServer struct {
	oauthProvider      oauth.OAuthProvider
	auditor            audit.Auditor
	blessingLogReader  auditor.BlessingLogReader
	revocationManager  revocation.RevocationManager
	oauthBlesserParams blesser.OAuthBlesserParams
	caveatSelector     caveats.CaveatSelector
	emailClassifier    *util.EmailClassifier
	rootedObjectAddrs  []naming.Endpoint
	assetsPrefix       string
}

// NewIdentityServer returns a IdentityServer that:
// - uses oauthProvider to authenticate users
// - auditor and blessingLogReader to audit the root principal and read audit logs
// - revocationManager to store revocation data and grant discharges
// - oauthBlesserParams to configure the identity.OAuthBlesser service
func NewIdentityServer(oauthProvider oauth.OAuthProvider, auditor audit.Auditor, blessingLogReader auditor.BlessingLogReader, revocationManager revocation.RevocationManager, oauthBlesserParams blesser.OAuthBlesserParams, caveatSelector caveats.CaveatSelector, emailClassifier *util.EmailClassifier, assetsPrefix string) *IdentityServer {
	return &IdentityServer{
		oauthProvider:      oauthProvider,
		auditor:            auditor,
		blessingLogReader:  blessingLogReader,
		revocationManager:  revocationManager,
		oauthBlesserParams: oauthBlesserParams,
		caveatSelector:     caveatSelector,
		emailClassifier:    emailClassifier,
		assetsPrefix:       assetsPrefix,
	}
}

// findUnusedPort finds an unused port and returns it. Of course, no guarantees
// are made that the port will actually be available by the time the caller
// gets around to binding to it. If no port can be found, (0, nil) is returned.
// If an error occurs while creating a socket, that error is returned and the
// other return value is 0.
func findUnusedPort() (int, error) {
	random := mrand.New(mrand.NewSource(time.Now().UnixNano()))
	for i := 0; i < 1000; i++ {
		fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
		if err != nil {
			return 0, err
		}

		port := int(1024 + random.Int31n(64512))
		sa := &syscall.SockaddrInet4{Port: port}
		err = syscall.Bind(fd, sa)
		syscall.Close(fd)
		if err == nil {
			return port, nil
		}
	}

	return 0, nil
}

func (s *IdentityServer) Serve(ctx *context.T, listenSpec *rpc.ListenSpec, externalHttpAddr, httpaddr, tlsconfig string) {
	ctx, err := v23.SetPrincipal(ctx, audit.NewPrincipal(
		v23.GetPrincipal(ctx), s.auditor))
	if err != nil {
		vlog.Panic(err)
	}
	httphost, httpport, err := net.SplitHostPort(httpaddr)
	if err != nil || httpport == "0" {
		httpportNum, err := findUnusedPort()
		if err != nil {
			vlog.Panic(err)
		}
		httpaddr = net.JoinHostPort(httphost, strconv.Itoa(httpportNum))
	}
	rpcServer, _, externalAddr := s.Listen(ctx, listenSpec, externalHttpAddr, httpaddr, tlsconfig)
	fmt.Printf("HTTP_ADDR=%s\n", externalAddr)
	if len(s.rootedObjectAddrs) > 0 {
		fmt.Printf("NAME=%s\n", s.rootedObjectAddrs[0].Name())
	}
	<-signals.ShutdownOnSignals(ctx)
	if err := rpcServer.Stop(); err != nil {
		vlog.Errorf("Failed to stop rpc server: %v", err)
	}
}

func (s *IdentityServer) Listen(ctx *context.T, listenSpec *rpc.ListenSpec, externalHttpAddr, httpaddr, tlsconfig string) (rpc.Server, []string, string) {
	// Setup handlers

	// json-encoded public key and blessing names of this server
	principal := v23.GetPrincipal(ctx)
	http.Handle("/auth/blessing-root", handlers.BlessingRoot{principal})

	macaroonKey := make([]byte, 32)
	if _, err := rand.Read(macaroonKey); err != nil {
		vlog.Fatalf("macaroonKey generation failed: %v", err)
	}

	rpcServer, published, err := s.setupServices(ctx, listenSpec, macaroonKey)
	if err != nil {
		vlog.Fatalf("Failed to setup vanadium services for blessing: %v", err)
	}

	externalHttpAddr = httpaddress(externalHttpAddr, httpaddr)

	n := "/auth/google/"
	h, err := oauth.NewHandler(oauth.HandlerArgs{
		Principal:               principal,
		MacaroonKey:             macaroonKey,
		Addr:                    fmt.Sprintf("%s%s", externalHttpAddr, n),
		BlessingLogReader:       s.blessingLogReader,
		RevocationManager:       s.revocationManager,
		DischargerLocation:      naming.JoinAddressName(published[0], dischargerService),
		MacaroonBlessingService: naming.JoinAddressName(published[0], macaroonService),
		OAuthProvider:           s.oauthProvider,
		CaveatSelector:          s.caveatSelector,
		EmailClassifier:         s.emailClassifier,
		AssetsPrefix:            s.assetsPrefix,
	})
	if err != nil {
		vlog.Fatalf("Failed to create HTTP handler for oauth authentication: %v", err)
	}
	http.Handle(n, h)

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		args := struct {
			Self                            security.Blessings
			GoogleServers, DischargeServers []string
			ListBlessingsRoute              string
			AssetsPrefix                    string
		}{
			Self:         principal.BlessingStore().Default(),
			AssetsPrefix: s.assetsPrefix,
		}
		if s.revocationManager != nil {
			args.DischargeServers = appendSuffixTo(published, dischargerService)
		}
		var emptyParams blesser.OAuthBlesserParams
		if !reflect.DeepEqual(s.oauthBlesserParams, emptyParams) {
			args.GoogleServers = appendSuffixTo(published, oauthBlesserService)
		}
		if s.blessingLogReader != nil {
			args.ListBlessingsRoute = oauth.ListBlessingsRoute
		}
		if err := templates.Home.Execute(w, args); err != nil {
			vlog.Info("Failed to render template:", err)
		}
	})
	vlog.Infof("Running HTTP server at: %v", externalHttpAddr)
	go runHTTPSServer(httpaddr, tlsconfig)
	return rpcServer, published, externalHttpAddr
}

func appendSuffixTo(objectname []string, suffix string) []string {
	names := make([]string, len(objectname))
	for i, o := range objectname {
		names[i] = naming.JoinAddressName(o, suffix)
	}
	return names
}

// Starts the blessing services and the discharging service on the same port.
func (s *IdentityServer) setupServices(ctx *context.T, listenSpec *rpc.ListenSpec, macaroonKey []byte) (rpc.Server, []string, error) {
	server, err := v23.NewServer(ctx)
	if err != nil {
		return nil, nil, fmt.Errorf("failed to create new rpc.Server: %v", err)
	}

	principal := v23.GetPrincipal(ctx)
	objectAddr := naming.Join("identity", fmt.Sprintf("%v", principal.BlessingStore().Default()))
	var rootedObjectAddr string
	if eps, err := server.Listen(*listenSpec); err != nil {
		defer server.Stop()
		return nil, nil, fmt.Errorf("server.Listen(%v) failed: %v", *listenSpec, err)
	} else if nsroots := v23.GetNamespace(ctx).Roots(); len(nsroots) >= 1 {
		rootedObjectAddr = naming.Join(nsroots[0], objectAddr)
		s.rootedObjectAddrs = eps
	} else {
		rootedObjectAddr = eps[0].Name()
		s.rootedObjectAddrs = eps
	}
	dispatcher := newDispatcher(macaroonKey, oauthBlesserParams(s.oauthBlesserParams, rootedObjectAddr))
	if err := server.ServeDispatcher(objectAddr, dispatcher); err != nil {
		return nil, nil, fmt.Errorf("failed to start Vanadium services: %v", err)
	}
	vlog.Infof("Blessing and discharger services will be published at %v", rootedObjectAddr)
	return server, []string{rootedObjectAddr}, nil
}

// newDispatcher returns a dispatcher for both the blessing and the
// discharging service.
func newDispatcher(macaroonKey []byte, blesserParams blesser.OAuthBlesserParams) rpc.Dispatcher {
	d := dispatcher(map[string]interface{}{
		macaroonService:     blesser.NewMacaroonBlesserServer(macaroonKey),
		dischargerService:   services.DischargerServer(discharger.NewDischarger()),
		oauthBlesserService: blesser.NewOAuthBlesserServer(blesserParams),
	})
	// Set up the glob invoker.
	var children []string
	for k, _ := range d {
		children = append(children, k)
	}
	d[""] = rpc.ChildrenGlobberInvoker(children...)
	return d
}

type allowEveryoneAuthorizer struct{}

func (allowEveryoneAuthorizer) Authorize(*context.T) error { return nil }

type dispatcher map[string]interface{}

func (d dispatcher) Lookup(suffix string) (interface{}, security.Authorizer, error) {
	if invoker := d[suffix]; invoker != nil {
		return invoker, allowEveryoneAuthorizer{}, nil
	}
	return nil, nil, verror.New(verror.ErrNoExist, nil, suffix)
}

func oauthBlesserParams(inputParams blesser.OAuthBlesserParams, servername string) blesser.OAuthBlesserParams {
	inputParams.DischargerLocation = naming.Join(servername, dischargerService)
	return inputParams
}

func runHTTPSServer(addr, tlsconfig string) {
	if len(tlsconfig) == 0 {
		vlog.Fatal("Please set the --tlsconfig flag")
	}
	paths := strings.Split(tlsconfig, ",")
	if len(paths) != 2 {
		vlog.Fatalf("Could not parse --tlsconfig. Must have exactly two components, separated by a comma")
	}
	vlog.Infof("Starting HTTP server with TLS using certificate [%s] and private key [%s] at https://%s", paths[0], paths[1], addr)
	if err := http.ListenAndServeTLS(addr, paths[0], paths[1], nil); err != nil {
		vlog.Fatalf("http.ListenAndServeTLS failed: %v", err)
	}
}

func httpaddress(externalHttpAddr, httpaddr string) string {
	// If an externalHttpAddr is provided use that.
	if externalHttpAddr != "" {
		httpaddr = externalHttpAddr
	}
	return fmt.Sprintf("https://%v", httpaddr)
}
